如果我有一个脚本将变量只读设置为一些奇数值,并且errexit
由于其他不安全的操作而设置:
#!/bin/bash
set -e
declare -r NOTIFY=$(case "$OS" in (macosx) echo macos_notify ;; (linux) echo linux_notify ;; (*) echo : ;; esac)
declare -r SAY=_say # _say is a function
declare -r VERSION=0.99
set +e
我第二次使用它来获取定义,因为它正在开发中:
$ . s.bash
$ . s.bash
bash: declare: NOTIFY: readonly variable
Exited
通常declare -r EXISTING_VAR
既不会停止脚本也不会删除EXISTING_VAR
.
但是对于errexit
,分配给现有变量是可以理解的失败。简单的选项是删除-r
或使用set +e
该部分脚本。
除此之外,如果名称已经存在,是否可以编写一个 Bash 函数来代替declare -r
但不重新分配?
我试过了:
# arg #1: var name, #2: value
set_var_once () {
# test whether the variable with the
# name stored in $1 exists
if [[ -z "${!1}" ]]
then # if it doesn't, set it
declare -r $1=$2
fi
}
我也尝试过类似的东西eval "declare -r $1=$(eval $2)"
,感觉eval
这里的某个地方需要,但我不确定在哪里。
所有版本的set_var_once
结果都没有设置他们应该设置的变量。
declare -r
使变量只读,但也在当前范围内声明它,因此使其成为当前函数的本地变量。相反,您只希望readonly
前者:用作:
请注意,由于与 相反
readonly
,thatreadonly_once
不是关键字(是的,即使隐藏了该事实也是关键字),因此readonly
需要引用以防止拆分 + glob,此时它不是赋值。bash
$(cmd)
$(cmd)
将被扩展(并因此cmd
运行),即使该值最终不会被分配(VAR2
如果它已经定义)。该函数仅适用于标量变量,不适用于数组或关联数组。
如果你的 shell 是 bash,你可以使用
-v
test
:例如
或者,使用
${param:=value}
扩展和:
命令演示:
我发现以下内容很有用
AbortScript 是我使用的另一个函数。它只是打印出错误消息,然后退出脚本。