Reputation: 317
I want to run 2 commands and output the exit status of the first command. And all this, I want to do it in a single line of command. Something like this
cmd1; cmd2 && echo $?-1
It should output the exit status of cmd1.
Upvotes: 8
Views: 4472
Reputation: 4543
If you have two commands as follows where you are checking the version of the first command to see if you have the correct version of the command installed:
#!/usr/bin/env bash
set -e
cmd1="my_command version"
cmd2="sleep 1"
exit_code=$(${cmd1}; status=$?; ${cmd2} && echo $status)
printf "_${exit_code}_"
if [[ "_${exit_code}_" == "_0_" && "$(my_command version)" =~ " 1." ]]; then
my_command
fi
The output could be the following if version
was a valid option or command of my_command
, where my_command 1.0.0
is the output of my_command version
and 0
is the exit code at the end. Note that I have used surrounded the value with _
just to make it clear:
_my_command 1.0.0
0_
And that would not satisfy the first condition of the if
statement.
But the output could be the following if the version of my_command
that was currently installed was a different version that only supported use of the option --version
and so use of my_command version
was invalid:
_1_
To resolve that issue I simply got the exit code from the last character with last_char=${exit_code: -1}
and changed the first condition of the if
statement to be "_${last_char}_" == "_0_"
instead
#!/usr/bin/env bash
set -e
cmd1="my_command version"
cmd2="sleep 1"
exit_code=$(${cmd1}; status=$?; ${cmd2} && echo $status)
last_char=${exit_code: -1}
printf "_${last_char}_"
if [[ "_${last_char}_" == "_0_" && "$(my_command version)" =~ " 1." ]]; then
my_command
fi
Upvotes: 0
Reputation: 295815
Like any other global variable that has its status updated over time (ie. errno
in C), if you want to refer to an old value, you need to store it ahead-of-time.
cmd1; cmd1_retval=$?; cmd2 && echo "$cmd1_retval"
The place where this is different, by the way, is in a pipeline:
cmd1 | cmd2 | cmd3
echo "${PIPESTATUS[$(( ${#PIPESTATUS[@]} - 2 ))]}"
That's because in a pipeline, all components run at once, and by default the exit status is that of the last one. In bash, however, the exit status of all components is stored in the PIPESTATUS
array; ${#PIPESTATUS[@]}
takes the length of this array, and subtracting two from it (one because of the difference between 0- and 1-based indexing, and one to get from the last item to the second-to-last item) gets the second-to-last item in the preceding pipeline.
Upvotes: 11