I am trying to print a string depending on the exit code of a test
built-in and ternary operator. I am successful to:
b=5
echo $(( b==5 ? good : bad )) # good is printed
good is printed as expected, but if I do:
echo $(( test $b -eq 50 ? 123 : 321 ))
test 5 -eq 50 ? 123 : 321 : syntax error in expression (error token is "5 -eq 50 ? 123 : 321 ")
echo $(( $(test $b -eq 5)==0 ? 123 : 321 ))
==0 ? 123 : 321 : syntax error: operand expected (error token is "==0 ? 123 : 321 ")
Let's say I want to report file existence, none of the following didn't work as well:
echo $(( $((test -e file))==0 ? 123 : 321 ))
test -e file: syntax error in expression (error token is "file")
echo $(( ((test -e file))==0 ? 123 : 321 ))
((test -e file))==0 ? 123 : 321 : missing `)' (error token is "file))==0 ? 123 : 321 ")
echo $(( (test -e file)==0 ? 123 : 321 ))
(test -e file)==0 ? 123 : 321 : missing `)' (error token is "file)==0 ? 123 : 321 ")
echo $(( "test -e file" ? 123 : 321 ))
"test -e file" ? 123 : 321 : syntax error: operand expected (error token is ""test -e file" ? 123 : 321 ")
Is it any possible construct in ternary operator that can examine an exit code?
The $(( arithmetic context ))
expects an arithmetic expression; obviously random strings (which apparently you hope to have executed as commands) are not arithmetic expressions, so that's a syntax error.
Probably try
echo $(( $(test "$b" -eq 50; echo $?) ? 123 : 321 ))
etc; but obviously, a much less convoluted and more idiomatic way to say this is
test "$b" -eq 50 && echo 123 || echo 321
You can't refactor the echo
out; in this isolated example, that's just a minor inconvenience. If you really need to avoid repeating more complex code, replace echo
with a function which encapsulates whatever it is that you don't want to repeat.
A $(command substitution)
replaces the command with whatever it prints to standard output. If you want to examine its exit code, you need it to print that (and nothing else) to standard output, or use a different construction.