【问题标题】:bash - Can local variable assignment return false?bash - 局部变量赋值可以返回false吗?
【发布时间】:2022-01-26 01:19:15
【问题描述】:

假设我有以下代码,其中is_wednesday 是一个函数,它在星期三返回 0,在其他日子返回 1。

print_wednesday() {
    is_wednesday && local WEDNESDAY="Yes!" || local WEDNESDAY="No!"
    echo "Is today Wednesday? $WEDNESDAY"
}

有没有办法给局部变量赋值会返回 1,在这个例子中会导致在星期三打印 Is today Wednesday? No!

【问题讨论】:

  • 只需使用正确的if then else,您就不必担心模糊的故障模式。
  • 如果我用truefalse 替换is_wednesday,那么我会得到描述的输出。不幸的是,我不清楚这个问题。
  • @GordonDavisson 也许我没有选择最好的例子。问题不在于构造,而纯粹是关于变量赋值的返回值。
  • @Cyrus A && B || C 不等于 if A; then B; else C; fi。如果 A 返回 true 而 B 返回 false,则 C 仍然被执行。因此,如果 local WEDNESDAY="Yes!" 可能以某种方式返回 false,则 local WEDNESDAY="No!" 将被执行,并且您将在星期三得到 No!
  • 我看不出有任何方法可以将固定字符串(此处:Yes!)分配给变量可以返回1(带有bash)。

标签: bash variables


【解决方案1】:

是的,(简单,语法正确)局部变量赋值可以返回 false。特别是,如果变量已经在代码中的其他地方声明了readonly,或者在函数外部使用declare -r 声明,就会发生这种情况。这个Shellcheck-clean 程序演示了这个问题:

#! /bin/bash -p

readonly WEDNESDAY='No!'

function test_local_return_value
{
    local WEDNESDAY='Yes!'
    echo "'local' returned $?"
    echo "WEDNESDAY='$WEDNESDAY'"
}

test_local_return_value

输出如下:

...: line 7: local: WEDNESDAY: readonly variable
'local' returned 1
WEDNESDAY='No!'

这是local 的一个严重限制,因为它意味着程序中其他地方的更改可能会破坏看似完全独立的函数。我在实践中看到了这种情况。由于readonly 创建了一个全局只读变量,即使它在函数中使用,问题也变得更糟。 readonly 需要非常小心地使用。它不应该在函数中使用(改用local -r),最好有一个命名约定,以确保readonly 变量名不会与其他变量名冲突。

readonly 问题在 Bash man 页面中进行了介绍(至少对于 Bash 版本 4.4)。 local 部分包括:“返回状态为 0,除非在函数外部使用 local、提供了无效名称或 name 是只读变量”。

【讨论】:

    【解决方案2】:

    局部变量赋值可以返回false吗?

    内置的local会:

    • --help 调用时返回2
    • 使用无效的-flags 调用时返回2
    • 如果没有在函数内部调用,则返回 1
    • 否则返回0
    • (或者整个 Bash 进程将终止,以防出现类似“内存不足”的错误)

    请注意,变量赋值(我的意思是,没有local)将返回最后执行的进程的退出状态。以下将打印No

    true && WEDNESDAY="Yes$(false)" || WEDNESDAY="No"
    echo "$WEDNESDAY"
    

    有没有办法给局部变量赋值会返回 1,在这个例子中会导致打印 Is today Wednesday?不!星期三?

    没有。


    我会推荐:

    • local 与分配分开
    • 不要使用&& ||链,始终使用if
    • 不要对局部变量使用大写变量。
    • 并按以下方式编写函数:

    print_wednesday() {
        local wednesday
        if is_wednesday; then
             wednesday="Yes"
        else
             wednesday="No"
        fi
        echo "Is today Wednesday? $wednesday!"
    }
    

    【讨论】:

    • 如果变量名无效,local 也会返回 1,例如local 3=something
    猜你喜欢
    • 2020-12-10
    • 2017-11-18
    • 1970-01-01
    • 2021-11-20
    • 1970-01-01
    • 1970-01-01
    • 2013-05-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多