Top posting intentionally as I don't think any (or much) context is required.
I am always impressed with Greg's knowledge of the Bash shell (maybe all shells), but, wow, Bash seems like a convoluted mess to keep track of all the little details / gotchas. Is there a shell that is better in that respect? Maybe the c-shell? I don't like c (because I have a hard time programming in it), but if the c-shell has less intricacies (and is quite consistent with the c language), then maybe (for me) it is worth switching to (someday ;-) Nothing new below this line. On Tuesday, October 20, 2020 07:36:39 AM Greg Wooledge wrote: > 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.)