1

If I do a simple test of exit codes directly with single commands:

[user@localhost ~]$ date Tue Sep 8 14:00:11 CEST 2020 [user@localhost ~]$ echo $? 0 [user@localhost ~]$ dat bash: dat: command not found... [user@localhost ~]$ echo $? 127 

But if I want to get them into an if sentence, I see that for the exit code 0 the output is OK, however, for the "command not found" code (it should be 127) it returns "1".

[user@localhost ~]$ date Tue Sep 8 14:02:18 CEST 2020 [user@localhost ~]$ if [ $? -eq 0 ]; then echo "Success: $?"; else echo "Failure: $?" >&2; fi Success: 0 [user@localhost ~]$ dat bash: dat: command not found... [user@localhost ~]$ if [ $? -eq 0 ]; then echo "Success: $?"; else echo "Failure: $?" >&2; fi Failure: 1 

What am I missing?

7
  • 6
    The [ command modifies $? too. Use: dat; status=$?; if [ $status = 0 ]; then echo "Success: $status"; else echo "Failure: $status"; fi. Commented Sep 8, 2020 at 12:11
  • 2
    The $? in the else clause is the exit status of [ $? -eq 0 ] in the if clause. Commented Sep 8, 2020 at 12:14
  • @ZumodeVidrio : Looks like a XY-problem to me. What your use case? What do you want to achieve? Commented Sep 8, 2020 at 13:19
  • @user1934428 No no, it's not an XY-problem at all, I was just trying to add some debug into a script and wanted to take into account the error code in case it happens. Commented Sep 8, 2020 at 14:14
  • Then, why only 0 and 127? Codes larger 127 are virtually always errors occuring when starting a process, and most programs use codes between 1 (or 2) and 126 for errors too. And why do you want to continue on failure? Wouldn't a set -e better fulfil what you want? Commented Sep 8, 2020 at 14:38

2 Answers 2

7

If you want to catch and print the exit code for each command, I would not bother saving it in a variable. This would be necessary only if you need this exit code agains at a later time, or if there are some non-zero exit codes which you don't regard as error.

Instead, I would do it like this:

Replace your existing

command_to_verify 

by

if command_to_verify then echo Success else echo Failure: $? fi 
Sign up to request clarification or add additional context in comments.

3 Comments

I had code very similar to this that was not working that led me to this question. if ! command_to_verify; then echo Failure: $?; fi was not working.
If you write, ! command_to_verify, the ! changes $?, and this is the reason why you loose the actual status value of your command.
1

Every command has it own exit state, so the command [ 1 will override $?. To prevent this, save the exit code to a variable, and use that in the if statement;

le=$? if [ "$le" -eq 0 ]; then echo "Success: $le"; else echo "Failure: $le" >&2; fi 

Try it online!


1: The single bracket [ is actually an alias for the test command, it's not syntax. For more info, check this comment on unix.stackexchange

1 Comment

I think printing $le in the success case is redundandt; we know that it must be 0 here.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.