0

I have the following executable files:

set_status.sh
    #!/bin/bash
    exit $1
tst_set_status.sh
    #!/bin/bash
1.  echo arg1 = $1
2.  ./set_status.sh $1
3.  stat=$?
4.  echo $?
5.  if [ $stat -eq 0 ]; then
6.    final_stat="ok"
7.  fi
8.  echo $stat
9.  echo `echo $?`

So:

./tst_set_status.sh 1

arg1 = 1
0
1
0

Questions:

  1. Why does $stat have the value 0 and not 1 at line 4? Is line 4 printing the result of the shell asignment on line 3?
  2. Which command exit status is the ? variable reporting in line 9?
Gary Aitken
  • 233
  • 2
  • 12
  • 1
    Sidenote: ``echo `echo $?` `` is redundant. Just do `echo $?`. – wjandrea Aug 30 '22 at 16:53
  • @wjandrea I don't think so. `echo $0` should (I think...) echo the value of ? at the start of the statement. echo `echo $0` (backquotes) should echo the value of ? after executing the echo $0 command. The echo command normally sets the exit status to 0, whereas 'echo $?' should print whatever ? was set to previously. – Gary Aitken Aug 30 '22 at 18:29
  • Beside the point, but `set_status.sh` is unnecessary. You can just use `false` to set `$?` to 1. – wjandrea Aug 30 '22 at 23:28
  • 1
    Honestly, your explanation doesn't make much sense. You also wrote `$0` instead of `$?`. I think you think variables are more dynamic than they actually are in Bash. So, to be clear, the evaluation order goes like this: ``echo `echo $?` `` -> variable expansion: ``echo `echo 0` `` -> command substitution: `echo 0`. So it should be clear that ``echo `echo 0` `` does the same thing as `echo 0` but with an extra step. – wjandrea Aug 30 '22 at 23:39
  • @wjandrea that was typos, my mistake. I would delete that comment if I could. But now I am really confused: `false; echo $?` prints 1. ok. So if echo returns 0, then why does `false; echo `echo $?`` print 1 and not 0? – Gary Aitken Aug 31 '22 at 04:22
  • I don't understand the question. `$?` turns into `1` after variable expansion, and `echo`'s return status doesn't affect that. The evaluation order is just like what I wrote before only with `1` instead of `0`. Are you confusing return status with output? In Bash, output is sent on stdout (as well as stderr); the return status (canonically, *exit status*) is only used to indicate success or failure. – wjandrea Aug 31 '22 at 14:02

1 Answers1

2

Why does $stat have the value 1 and not 0 on line 6?

Because tar (or whatever was immediately before line 1) exited with a status of 1. $stat got the value of 1 on line 1, and didn't change afterwards.

The question you didn't ask is "why does echo $? print 0 on line 2?" And that's because the assignment on line 1 was a success, and so $? was reset to 0 before line 2.

Which command exit status is the ? variable reporting in line 7

The exit status of the echo on line 6.

hobbs
  • 223,387
  • 19
  • 210
  • 288
  • I presume the answer to this question is correct, although I'm mildly surprised that an assignment changes $? since it's not a command. – xpusostomos Aug 30 '22 at 17:18
  • @xpusostomos I wasn't sure myself so I tested it. `false ; foo=$? ; echo $? $foo` prints `0 1`. – hobbs Aug 30 '22 at 17:28
  • I've reformatted / fixed the code, which changed line numbers. I'm not worried about question 2 but left it in for consistency. Please note question 1 which now refers to line 4. And @hobbs thanks, the shell asignment setting the exit status is what screwed me up. – Gary Aitken Aug 30 '22 at 20:48
  • 2
    @xpusostomos an assignment can fail (for example if you try to write to a `readonly` variable or if you give an invalid arithmetic expression to a variable marked with `declare -i`) so there are niche use cases for checking the success of an assignment. – tjm3772 Aug 30 '22 at 21:08
  • @tjm3772 Less niche is to check if a command substitution succeeded, e.g. you could do something like `git_branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null) && echo "Currently on git branch: $git_branch"` – wjandrea Aug 30 '22 at 23:25
  • @tjm3772 sure, but in that case a command gets run... which raises the question, if there is command substitution does $? contain the result of the successful assignment or the result of the command run inside the assignment. apparently it's the command, but that's a bit weird. – xpusostomos Sep 01 '22 at 00:36