在 bash 中使用单个命令为 shell 变量分配默认值
Posted
技术标签:
【中文标题】在 bash 中使用单个命令为 shell 变量分配默认值【英文标题】:Assigning default values to shell variables with a single command in bash 【发布时间】:2011-01-02 01:58:18 【问题描述】:我在 bash (3.00) shell 脚本中对变量进行了一大堆测试,如果没有设置变量,那么它会分配一个默认值,例如:
if [ -z "$VARIABLE" ]; then
FOO='default'
else
FOO=$VARIABLE
fi
我似乎记得有一些语法可以在一行中执行此操作,类似于三元运算符,例如:
FOO=$ $VARIABLE : 'default'
(虽然我知道那行不通……)
我是疯了,还是有类似的事情存在?
【问题讨论】:
shell 参数扩展部分的 bash shell 参考是一个很好的起点:tiswww.case.edu/php/chet/bash/bashref.html#Shell-Expansions。 Shell Parameter Expansion 的 Gnu.org 文档(提示:您还可以做很多其他很酷的事情!) 【参考方案1】:对于命令行参数:
VARIABLE="$1:-$DEFAULTVALUE"
它将传递给脚本的第一个参数的值分配给VARIABLE
,如果没有传递这样的参数,则分配DEFAULTVALUE
的值。引用可以防止通配符和分词。
【讨论】:
【参考方案2】:实际上与您发布的内容非常接近。您可以使用名为 Bash parameter expansion 的东西来完成此操作。
要获取分配的值,或者default
(如果缺少):
FOO="$VARIABLE:-default" # If variable not set or null, use default.
# If VARIABLE was unset or null, it still is after this (no assignment done).
或者将default
同时赋值给VARIABLE
:
FOO="$VARIABLE:=default" # If variable not set or null, set it to default.
【讨论】:
如果我想在文档中找到这个,谷歌会做什么?使用 $:- 等特殊字符进行谷歌搜索并不容易。 请注意,它是not bash-specific,适用于整个 shell 系列。通用脚本是安全的。 @solarmist 关键字是“bash 参数扩展”,如果您想了解更多关于它及其同伴的信息。 这里对unix.stackexchange.com/a/122848/2407这个话题有更深入的解释【参考方案3】:见3.5.3(shell参数扩展)下的here
在你的情况下
$VARIABLE:-default
【讨论】:
【参考方案4】:还有一种更简洁地表达“if”结构的方法:
FOO='default'
[ -n "$VARIABLE" ] && FOO=$VARIABLE
【讨论】:
【参考方案5】:即使你可以像默认值一样使用另一个变量的值
有一个文件defvalue.sh
#!/bin/bash
variable1=$1
variable2=$2:-$variable1
echo $variable1
echo $variable2
运行./defvalue.sh first-value second-value
输出
first-value
second-value
然后运行./defvalue.sh first-value
输出
first-value
first-value
【讨论】:
【参考方案6】:如果变量相同,那么
: "$VARIABLE:=DEFAULT_VALUE"
如果未定义,则将 DEFAULT_VALUE
分配给 VARIABLE
。双引号可防止通配符和分词。
另请参阅 Bash 手册中的第 3.5.3 节,Shell Parameter Expansion。
【讨论】:
这个棘手的技巧对我来说并不明显,使用 : no-effect builtin 来吃 $.. 的扩展但留下 VARIABLE 集。到目前为止,我一直在这样做: VARIABLE="$VARIABLE:-DEFAULT_VALUE" 并且因为使用 VARIABLE 两次而感到愚蠢。 事实证明这并不总是适用于 BASH 内置变量。这非常非常奇怪。目前我知道的是HISTTIMEFORMAT
如何设置多个默认值?我试过 ": $VARIABLE:=DEFAULT_VALUE : $VARIABLE2:=DEFAULT_VALUE2" 但这似乎不起作用......
@Hans:冒号是命令(什么都不做),因此只需要一次。例如。 : $FOO:=DEFAULT1 $BAR:=DEFAULT2
有机会在export
中使用类似的东西吗?我想让这个变量可用于从当前脚本调用的脚本。【参考方案7】:
这是一个例子
#!/bin/bash
default='default_value'
value=$1:-$default
echo "value: [$value]"
将其保存为 script.sh 并使其可执行。 不带参数运行它
./script.sh
> value: [default_value]
使用参数运行它
./script.sh my_value
> value: [my_value]
【讨论】:
【参考方案8】:FWIW,您可以提供如下错误消息:
USERNAME=$1:?"Specify a username"
这会显示这样的消息并以代码 1 退出:
./myscript.sh
./myscript.sh: line 2: 1: Specify a username
一个更完整的例子:
#!/bin/bash
ACTION=$1:?"Specify 'action' as argv[1]"
DIRNAME=$2:-$PWD
OUTPUT_DIR=$3:-$HOMEDIR:-"/tmp"
echo "$ACTION"
echo "$DIRNAME"
echo "$OUTPUT_DIR"
输出:
$ ./script.sh foo
foo
/path/to/pwd
/tmp
$ export HOMEDIR=/home/myuser
$ ./script.sh foo
foo
/path/to/pwd
/home/myuser
$ACTION
取第一个参数的值,如果为空则退出
$DIRNAME
是第二个参数,默认为当前目录
$OUTPUT_DIR
是第三个参数,或 $HOMEDIR
(如果已定义),否则为 /tmp
。这适用于 OS X,但我不确定它是否可移植。
【讨论】:
【参考方案9】:回答您的问题和所有变量替换
echo "$var"
echo "Substitute the value of var."
echo "$var:-word"
echo "If var is null or unset, word is substituted for var. The value of var does not change."
echo "$var:=word"
echo "If var is null or unset, var is set to the value of word."
echo "$var:?message"
echo "If var is null or unset, message is printed to standard error. This checks that variables are set correctly."
echo "$var:+word"
echo "If var is set, word is substituted for var. The value of var does not change."
您可以通过在美元符号和表达式的其余部分之间放置一个 \ 来转义整个表达式。
echo "$\var"
【讨论】:
还有var-default
,其中default
仅在var
未定义时使用。如果定义了var
但为空,则不会使用default
。
为什么每行都有一个反斜杠?其他答案没有。以上是关于在 bash 中使用单个命令为 shell 变量分配默认值的主要内容,如果未能解决你的问题,请参考以下文章