题 什么命令意味着在Bash中有条件地“无所事事”?


有时在制作条件时,我需要代码什么都不做,例如,在这里,我希望Bash什么都不做 $a 如果大于“10”,则打印“1” $a 小于“5”,否则,打印“2”:

if [ "$a" -ge 10 ]
then
elif [ "$a" -le 5 ]
then
    echo "1"
else
    echo "2"
fi

这会产生错误。是否有一个命令什么都不做,也不会减慢我的脚本?


115
2017-07-11 01:24


起源




答案:


shell中的no-op命令是 : (结肠)。

if [ "$a" -ge 10 ]
then
    :
elif [ "$a" -le 5 ]
then
    echo "1"
else
    echo "2"
fi

来自 bash手册

: (冒号)
  除了扩展参数和执行重定向之外什么都不做。返回状态为零。


227
2017-07-11 01:26



对于教育来说,:是一个运营“真实”的运营商。在这样的情况下,我非常喜欢它,因为它更容易阅读。 - SaintHax
@SaintHax不,它没有运行 true。它内置于shell中,不执行任何操作。 - Barmar
它是shell内置的(你是正确的),它返回true(状态0)就像true一样,并且它更难以阅读。 Bash是DevOps语言,如果 : 是由我的团队成员写的,我让他们改变它。 - SaintHax
@SaintHax如果有人用过 true 在非条件的背景下,我会让他们改变它。 if true 很好, then true 似乎错了。 - Barmar
当然,您只需重写要使用的代码即可 if ! condition; then do something; fi 代替 if condition; then :; else do something; fi。 - Barmar


你可以只使用 true 命令:

if [ "$a" -ge 10 ]; then
    true
elif [ "$a" -le 5 ]; then
    echo "1"
else
    echo "2"
fi

在您的示例案例中(但不一定无处不在),另一种方法是重新排序if / else:

if [ "$a" -le 5 ]; then
    echo "1"
elif [ "$a" -lt 10 ]; then
    echo "2"
fi

28
2017-07-11 01:26



如果你不测试结果 true 和 false 就剧本而言,它们实际上是无操作的,但原则上它们 可以 在一些接受这种语法的shell中分叉也许 : 更好。 - dmckee
问题是标记为bash。在bash, true 和 false 是内置的。对于旧壳, true, false, 乃至 : 可能是外部命令(虽然你可能只看到后者) 非常 旧壳)。 - Keith Thompson
我更喜欢 : 仅仅因为它更明确意图是什么 - Freedom_Ben


虽然我没有回答关于无操作命令的原始问题,但是当人们想到时,很多(如果不是大多数)问题“在这个分支我不得不做什么“可以简单地绕过 重组逻辑 这样就不会发生这个分支。

我尝试使用OPs示例给出一般规则

当$ a大于“10”时什么都不做,如果$ a小于“5”则打印“1”,否则打印“2”

我们必须避免分支在哪里 $a 得到10以上,所以 $a < 10 作为一般条件可以适用于所有其他条件。

一般而言,当你说 X时什么也不做,然后将其改写为 避免X所在的分支。通常,您可以通过简单地否定X并将其应用于所有其他条件来避免发生。

因此,应用规则的OP示例可能会重构为:

if [ "$a" -lt 10 ] && [ "$a" -le 5 ]
then
    echo "1"
elif [ "$a" -lt 10 ]
then
    echo "2"
fi

只是上面的一个变体,将所有内容都包含在内 $a < 10 条件:

if [ "$a" -lt 10 ]
then
    if [ "$a" -le 5 ]
    then
        echo "1"
    else
        echo "2"
    fi
fi

(对于这个具体的例子 @Flimzys重组 当然更好,但我想为所有寻求如何做无所求的人提供一般规则。)


8
2018-01-12 04:30



有人可能想要无操作的一个原因是,最初构建代码的想法是,人们会添加“稍后添加内容”,而不会产生无意的副作用。例如。如果你把一个if-then-else-fi放在.bashrc中,如果你放了 echo "put stuff here" 它会打破一些非登录用途(例如scp被破坏),只有空格/注释会导致运行时错误。 - Aphoid