Bash Exit Status Always Fails Comparison

140 views Asked by At

In my .bashrc...

46 function exitstatus()
47 {
48  local a=0
49  local s=$1
50  s=$s+1
51  a=$a+1
52  echo -n ' arg1='$s' a='$a
53  s=$1
54  a=0
55  echo  ' arg1='$s' a='$a
56
57  if [[ "$s" = "$a" ]]; then
58      echo "true"
59  else
60      echo "false"
61  fi
62 }
63
64 function myprompt {
65  local        ss=\$?
66  unset PS1
67  PS1="exit:\$? var:$ss exitstatus $ss $(exitstatus $ss) \n\t $ "
68 }
69 myprompt

exitstatus always evaluates to false, even when variable s and a appear to be the same string:

23:36:55 $ true
exit:0 var:0 exitstatus 0  arg1=0+1 a=0+1 arg1=0 a=0
false
23:36:56 $ false
exit:1 var:1 exitstatus 1  arg1=1+1 a=0+1 arg1=1 a=0
false

Lines 50 and 52 have demonstrated to me that s is being treated as a string so I compare it as a string in line 57. The comparison works as expected if I compare s to itself or a to itself because exitstatus always evaluates to true. For some reason exit status $? as an argument to exitstatus is not being handled as I expect.

What am I missing?

2

There are 2 answers

1
Socowi On

Since you defined PS1="..." with double quotes, the subshell $(exitstatus ...) is only evaluated once when the shell starts up. After that, the result from that one evaluation is a literal part of your prompt and won't change anymore.

Minimal Example

In this interactive shell session I execute one command per second. date +%s prints the seconds of the current time. I use true as command because it prints nothing.

$ PS1="$(date +%s) "
23 true
23 true
23 PS1='$(date +%s) '
26 true
27 true

As we can see, with double quotes the subshell is evaluated only once whereas with single quotes the subshell is expanded each time the prompt is printed. Of course you could also write PS1="\$(date +%s) " to the get an updating prompt.

0
TheDavisChanger On

This is what ultimately worked. I got rid of myprompt and used exitstatus to change the colors of my prompt:

function exitstatus { if [[ $? != 0 ]]; then echo -e "\e[48;5;52m"; fi; }
unset PS1 PS2 PS4
PS1='$(exitstatus) $'