[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Zoom.



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.)


Reply to: