直接在bash中打印条件结果而不使用if

cto*_*mek 13 shell bash test

假设我有这个简单的代码:

echo "Are there any arguments?"
if [ $# -eq 0 ]; then
    echo "false"
else
    echo "true"
fi
Run Code Online (Sandbox Code Playgroud)

如您所见,最好有机会直接打印条件结果,但我不知道该怎么做。

它会是这样的:

echo "$([ $# -eq 0 ])"

但它不是那样工作的。我们可以在没有的情况下做到这一点if吗?

mr.*_*tic 12

在这种情况下,您可以使用列表控制运算符 &&||而是:

[[ $# -eq 0 ]] && echo false || echo true

[[ $# -eq 0 ]] && { echo false; } \
               || { echo true; }
Run Code Online (Sandbox Code Playgroud)

{ }组命令的列表,你不需要他们的只是一个单一的命令,但他们经常做这样的结构更具有可读性(虽然名单还需要终止;或换行)。

正如@Kusalananda指出的,这可以用于简单代码(例如echo),其中的命令返回0(“真”):尽管词汇相似度上述具有相同的语义在C那样,即,短路评价:

(argc==1) && printf("false\n") || printf("true\n");  /* C, not bash */
Run Code Online (Sandbox Code Playgroud)

命令可能返回非零状态的解决方法是:

[[ $# -eq 0 ]] && { echo false;:; } || { echo true; }
Run Code Online (Sandbox Code Playgroud)

其中:第一个列表末尾的额外“ ” null 命令确保它返回 0(真)状态(列表的返回状态是列表中执行的最后一个命令的退出状态)。

虽然注意上面的逻辑是为了匹配问题而与普通条件逻辑测试相反,但通常的逻辑是

[[ boolean-condition ]] && { true-actions;:; } || { false-actions; }
Run Code Online (Sandbox Code Playgroud)

或者,对于这个例子更清楚:

[[ $# -eq 0 ]] && { echo no arguments;:; } || { echo found arguments; }
Run Code Online (Sandbox Code Playgroud)

当您有两个(或其他定义数量的状态)时,您还可以使用带有计算索引的数组,如 Stéphane 的回答所示:

declare -a bool=([1]=true [0]=false)
echo ${bool[ (($# == 0)) ]}
Run Code Online (Sandbox Code Playgroud)

或者

temperature=70
declare -a porridge=([1]="too hot" [2]="just right" [3]="too cold")
echo ${porridge[ (( temperature >= 75 ? 1 :
                    temperature <= 68 ? 3 : 2 )) ]}
Run Code Online (Sandbox Code Playgroud)

这在 中使用算术表达式(( )),其中 0 为假,与通常的 shell 约定相反。

  • 但请注意,语句的语义因此略有改变。如果前面的命令中的任何一个返回非零退出状态,则将执行最后一个命令。这意味着使用 `... &amp;&amp; ... || ...` 通常不是 `if ...; 的良好替代品。然后 ...; 别的 ...; fi`。 (2认同)

cho*_*oba 2

您可以使用$?它保留最后执行的命令的退出代码:

echo "Are there any arguments?"
[ $# -eq 0 ]
echo $?
Run Code Online (Sandbox Code Playgroud)