我可以检查三元运算符中的退出代码吗?

Can I examine exit code within ternary operator?

我正在尝试根据 test 内置和三元运算符的退出代码打印一个字符串。我成功了:

b=5
echo $(( b==5 ? good : bad ))   # good is printed

good 按预期打印,但如果我这样做:

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 ")

假设我想报告文件存在,以下 none 也不起作用:

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 ")

三元运算符中是否有任何可能的构造可以检查退出代码?

$(( arithmetic context ))需要一个算术表达式;显然随机字符串(显然你希望作为命令执行)不是算术表达式,所以这是一个语法错误。

大概试试

echo $(( $(test "$b" -eq 50; echo $?) ? 123 : 321 ))

等;但显然,一种更简单、更地道的说法是

test "$b" -eq 50 && echo 123 || echo 321

你无法重构 echo;在这个孤立的例子中,这只是一个小小的不便。如果您确实需要避免重复更复杂的代码,请将 echo 替换为封装您不想重复的任何内容的函数。

A $(command substitution) 将命令替换为打印到标准输出的任何内容。如果你想检查它的退出代码,你需要它把它(而不是别的)打印到标准输出,或者使用不同的结构。

或者,使用数组索引。

典型构造:

b=5
str=(bad good)
echo "${str[b==5]}"

这使用算术比较的输出作为数组索引。

字符串作为消息

您可以将消息数组构建为:

MSGS=('Good result' 'Wrong result' [123]='Existing entry' [321]='Broken link')

然后你需要一些常数:

good=0 bad=1 exist=123 notexist=321

然后使用整数作为:

b=5 file=/tmp
printf "B: %s %s, Entry: '%s' %s\n"   "$b" "${MSGS[ b==5 ? good : bad ]}" \
       "$file" "${MSGS[ $(test -e "$file";echo $?) ? notexist : exist ]}"
B: 5 Good result, Entry: '/tmp' Existing entry

b=12 file=/tnt
printf "B: %s %s, Entry: '%s' %s\n"   "$b" "${MSGS[ b==5 ? good : bad ]}" \
       "$file" "${MSGS[ $(test -e "$file";echo $?) ? 321 : 123 ]}"
B: 12 Wrong result, Entry: '/tnt' Broken link

快游戏示例:

简单使用消息数组选择数字游戏。

GAMMSGS=(Exact 'Too small' 'Too big')  target=$((RANDOM%10))  ANSWER=''
while [ "$ANSWER" != "Exact" ]; do
    read -n 1 -p 'Enter a digit: ' play
    ANSWER=${GAMMSGS[ target == play ? 0 : target > play ? 1 : 2 ]}
    echo -e \nYou try $play: $ANSWER
done

样本运行:

Enter a digit: 0
You try 0: Too small
Enter a digit: 9
You try 9: Too big
Enter a digit: 5
You try 5: Too big
Enter a digit: 3
You try 3: Exact