On Tue, Oct 20, 2020 at 06:36:15AM -0400, Dan Ritter wrote: > I have this in my PS1 definition: > > \$(if [[ \$? == 0 ]]; then echo \"+\"; else echo \"-\"; fi)\ > > Which has the effect of telling me the rough exit status of the > last command in my prompt.
The weird backslashing tells me you're defining PS1 with double quotes instead of single quotes, which is weird, and probably indicates that you're doing even worse things, like dynamically generating pieces of your PS1... I've seen things... things that no man should see.... Anyway, in addition to the weird quoting and possible abominations unrevealed, your command substitution forks. Every time the prompt is drawn, a new process is forked, just to do that simple "if" check. The standard workaround for that is to use an array variable with the two possible outcomes, and a bit of arithmetic. unicorn:~$ green=$(tput setaf 2) red=$(tput setaf 1) normal=$(tput sgr0) unicorn:~$ status=(+ -) statcolor=("$green" "$red") unicorn:~$ PS1='\[${statcolor[!!$?]}\]${status[!!$?]}\[$normal\] \h:\w\$ ' + unicorn:~$ true + unicorn:~$ false - unicorn:~$ true + unicorn:~$ (You can't see the colors in the mailing list, but they're there.) Just remember the basics: 1) Use single quotes around your definition of PS1, because you want all of the parts of it to be taken literally, and quoting is already hard enough without making it worse. 2) Variable expansions are "free" (do not cost a process fork). This includes variables that are set by PRMOPT_COMMAND, which is the more efficient way to set variables dynamically if you *really* need that, which you probably don't. 3) Color and other terminal escape codes can and should be stored in variables, which you can expand in PS1, as long as the PS1 definition is single-quoted. Don't store raw terminal sequences, because they are not the same for all terminals. This is what tput(1) is for. 4) Terminal escape sequences that don't change the cursor position should be enclosed in \[ \] so the shell knows where the cursor is at all times. 5) When expanding the index of an indexed array variable, the square brackets are a math context. In a math context, !!$? means "negate the previous command's exit status twice". So, 0 -> 1 -> 0, or nonzero -> 0 -> 1. Thus, !!$? always expands to either 0 or 1. And because it's in single quotes, it shouldn't trip history expansion, if you still have history expansion turned on. (I don't.)