假设我有这个简单的代码:
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]}"
(假设ksh93
、bash
或zsh
在 ksh 仿真中)。
在任何 POSIX shell 中,
echo "$(($# != 0))"
将输出1
true 和0
false。
答案3
您可以使用$?
它保留最后执行的命令的退出代码:
echo "Are there any arguments?"
[ $# -eq 0 ]
echo $?
答案4
由于我还不能发表评论(代表不足),我将在新答案中指出先生-spuratic的解决方案也适用于单括号,如下所示:
[ $# -eq 0 ] && { echo false; } || { echo true; }