user1317752 user1317752 - 2 months ago 8
Bash Question

Two styles of check return value in ksh

In ksh shell, I wanna to check the return value after running a command, I've wrote two styles:

if [ $? -ne 0 ] ; then
echo "failed!"
exit 1
else
exit 0
fi


[ $? -ne 0 ] && echo "failed!" && exit 1


Are they equivalent? If not, what could I do if I wanna to write it in one line?

Answer

They're close, but not the same. First, the if will execute the exit 1 even if the echo failed for some reason; the chained expression won't. Also, the chained version lacks an equivalent of the else exit 0.

A better equivalent would be this:

[ $? -ne 0 ] && { echo "failed!"; exit 1; } || exit 0

This is tagged ksh, so you might find the numeric expression syntax cleaner:

(( $? )) && { echo "failed!"; exit 1; } || exit 0

But you can also write an if on one line, if you like:

if (( $? )); then echo "failed!"; exit 1; else exit 0; fi

If the command that you just ran above this expression in order to set $? is short, you may want to just use it directly as the if expression - with reversed clauses, since exit code 0 is true:

if grep -q "pattern" /some/filename; then exit 0; else echo "failed!"; exit 1; fi

It doesn't matter for this simple case, but in general you probably want to avoid echo. Instead, use printf - or if you don't mind being ksh-only, you can use print. The problem with echo is that it doesn't provide a way to deal with weird strings in variables:

$ x=-n
$ echo "$x"
$ 

While both printf and print do:

$ printf '%s\n' "$x"
-n
$ print - "$x"
-n

Again, not a problem here, or any time you're just printing out a literal string, but I found it was easier to train myself out of the echo habit entirely.

Comments