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

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

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

echo "Are there any arguments?"
if [ $# -eq 0 ]; then
    echo "false"
else
    echo "true"
fi

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

它会是这样的:

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

但事实并非如此。我们可以在没有 的情况下做到这一点if吗?

答案1

在这种情况下,您可以使用列表控制操作员 &&而是||

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

[[ $# -eq 0 ]] && { echo false; } \
               || { echo true; }

{ }命令列表分组,您不需要将它们仅用于单个命令,但它们通常会使此类结构更具可读性(尽管列表也需要终止符;或换行符)。

正如 @Kusalananda 所指出的,这适用于echo命令返回 0(“true”)的简单代码(例如 ):尽管上面的词法相似才不是与 C 中的短路求值具有相同的语义,即:

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

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

[[ $# -eq 0 ]] && { echo false;:; } || { echo true; }

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

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

[[ boolean-condition ]] && { true-actions;:; } || { false-actions; }

或者,为了让这个例子更清楚:

[[ $# -eq 0 ]] && { echo no arguments;:; } || { echo found arguments; }

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

declare -a bool=([1]=true [0]=false)
echo ${bool[ (($# == 0)) ]}

或者

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

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

答案2

你可以这样做:

bool=(false true)
echo "${bool[$# != 0]}"

(假设ksh93bashzsh在 ksh 仿真中)。

在任何 POSIX shell 中,

echo "$(($# != 0))"

将输出1true 和0false。

答案3

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

echo "Are there any arguments?"
[ $# -eq 0 ]
echo $?

答案4

由于我还不能发表评论(代表不足),我将在新答案中指出先生-spuratic的解决方案也适用于单括号,如下所示:

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

相关内容