【问题标题】:What command means "do nothing" in a conditional in Bash?什么命令在 Bash 的条件中意味着“什么都不做”?
【发布时间】:2013-07-09 03:30:56
【问题描述】:

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

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

虽然这会出错。是否有一个命令不会执行任何操作,也不会减慢我的脚本速度?

【问题讨论】:

    标签: bash conditional noop


    【解决方案1】:

    shell中的no-op命令是:(冒号)。

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

    来自bash manual

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

    【讨论】:

    • @SaintHax 不,它不运行true。它内置在 shell 中,什么都不做。
    • 它是内置的shell(你是对的),它返回true(状态0)就像true一样,而且更难阅读。 Bash 是一种 DevOps 语言,如果 : 是我团队中的某个人编写的,我会让他们更改它。
    • @SaintHax 如果有人在非条件上下文中使用true,我会让他们更改它。 if true 很好,then true 好像不对。
    • 当然,您可以简单地重写代码以使用if ! condition; then do something; fi 而不是if condition; then :; else do something; fi
    • 我同意你的看法。这个例子可以用复合条件写成 if/elif/else 会更好。
    【解决方案2】:

    您可能只使用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
    

    【讨论】:

    • 如果您不测试结果,就脚本而言,truefalse 实际上都是无操作的,但原则上它们可以分叉在一些接受这种语法的 shell 中,所以: 可能更好。
    • 问题被标记为 bash。在 bash 中,truefalse 是内置的。对于较旧的 shell,truefalse 甚至 : 可能是外部命令(尽管您可能只会在 非常 旧的 shell 中看到后者)。
    • 我更喜欢:,因为它的意图更明确
    • 结果false 可能不是空操作,因为如果使用set -e(非零退出),那么false 将导致脚本立即退出。 true 是一个更好的无操作。 : 是一个真正的无操作,但我不得不承认它是不可读的,我已经编写 bash 30 年了,但我不知道它......
    【解决方案3】:

    虽然我没有回答关于 no-op 命令的原始问题,但是当人们认为“在这个分支中我什么都不做”时,许多(如果不是大多数)问题可以被绕过通过简单地重构逻辑,这样这个分支就不会发生了。

    我尝试通过使用 OP 示例给出一般规则

    $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 restructuring 肯定更好,但我想给所有搜索如何什么都不做的人提供一个通用规则。)

    【讨论】:

    • 某人可能想要无操作的一个原因是,在最初构建代码时,会考虑添加“稍后在此处添加内容”而不会产生无意的副作用。例如。如果将 if-then-else-fi 放入 .bashrc,如果您放入 echo "put stuff here",它将破坏一些非登录用途(例如 scp 被破坏),并且只有空格/cmets 会导致运行时错误.
    • 另外,就个人而言,我更喜欢编写更“人性化”的代码。通常可以将代码重组为更简洁甚至更高效。但是当这不是关键时,我更喜欢我的代码对于之后出现的任何开发人员来说都更具可读性。 (我也喜欢评论我的代码。)
    猜你喜欢
    • 2017-02-13
    • 1970-01-01
    • 2012-03-17
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 2016-02-28
    • 2017-03-22
    相关资源
    最近更新 更多