How to check for command exit code inside if statement
Solution 1
Your script is not doing what you want because, when timeout -t 10 command
has an exit status of 0 -- which is the exit status that is regarded as true in shell scripting -- the command timeout -t 10 command || [ $? = 143 ]
just completes with an exit status of 0 and does not cause the right-hand side of ||
to be run. Similarly, if you replaced ||
with &&
, then any nonzero exit status from the left-hand side would be the exit status of the whole command and the right-hand side would not be run.
You should just run them as two separate commands by separating them with a ;
or a newline. If necessary, you can still use them both as the if
condition when you do that (see below).
I am assuming that it is the exit status of timeout -t 10 command
, and not command
(if different), that you need. Otherwise it is unclear to me what you want; like ilkkachu, I am unfamiliar with a timeout
command that accepts a -t
option. Normally I would suggest that you do it this way, except that it sounds like your "external constraint" might prohibit it, since it doesn't use if
at all:
timeout -t 10 command
test "$?" -eq 143
exit
The test
/[
command returns an exit code of 0 to indicate true and 1 to indicate false, which is why you don't have to write separate branches with exit 0
and exit 1
. The exit
builtin, when run with no arguments, causes the shell to return the exit status of the last command that ran.
If you are already at the end of the script, then you can omit exit
, because when control flows off the end of a script, it has the same effect as exit
:
timeout -t 10 command
test "$?" -eq 143
(In either case, you can write [ "$?" -eq 143 ]
instead of test "$?" -eq 143
if you like. See below for details on [
/test
usage.)
Although your description made it sound like you cannot use that code exactly, you should nonetheless be able to modify it to take the required form. You said you must not merely do the check but also start the command in the if
clause. This seems to prohibit the readable and idiomatic approach suggested by Hauke Laging of running the command before the if
.
So if you can't do that, then you can include the command in the if
condition as you were doing, but separate it from your test
/[
command with a ;
rather than a ||
:
if timeout -t 10 command; [ "$?" -eq 143 ]; then
exit 0
else
exit 1
fi
(You can get away with omitting "
"
around $?
. You can also get away with writing =
instead of 143
, though it is confusing because =
signifies textual rather than numeric comparison. You can write test "$?" -eq 143
instead of [ "$?" -eq 143 ]
if you like.)
The reason this works is that you are permitted to write an if
condition that consists of multiple commands separated by semicolons or even newlines. That's why the shell grammar requires you to write then
to indicate the end of the if
condition. Therefore you do not have to attempt circuitous usage of the &&
or ||
operator when your goal is to run two commands as an if
condition while causing if
to itself test only the second.
Note that I am only suggesting this because you said it had to all be in the if
condition. I don't recommend scripting like that when you don't have to.
Solution 2
timeout -t 10 command
if [ $? -eq 143 ]; then
exit 0
else
exit 1
fi
Related videos on Youtube
Dremor
Updated on September 18, 2022Comments
-
Dremor almost 2 years
I'm trying to return a 0 exit code if a command exit with the a code 143 (timeout, from the "timeout command"), 1 otherwise. Due to external constraint (CI script), I have to start the command and do the check in the if clause.
Here is what I currently use :
if timeout -t 10 *command* || [ $? = 143 ] then exit 0 else exit 1 fi
At the moment, it always exit with a 0 code.
-
ilkkachu about 6 yearswhat
timeout
command is that? Does it return the exit code of the command it runs? -
ilkkachu about 6 yearsI'm asking because the one I know (in GNU coreutils, man page) doesn't take a
-t
flag and returns 124 on timeout, the same seems to apply to the FreeBSD one.
-
-
ilkkachu about 6 yearsWhat if
timeout
returns 0? -
Hauke Laging about 6 years@ilkkachu I just corrected the
if
handling. I have no idea whether the semantics are useful. -
Dremor about 6 yearsAfter reading your answer, I tried an one-liner version as following:
if timeout -t 30 command; [ "$?" -eq 143 ]; then exit 0; else exit 1; fi
. It worked quite well.