在 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 变量分配默认值的主要内容,如果未能解决你的问题,请参考以下文章

bash shell环境变量

Bash Shell中的通配符及转义字符的使用

基本bash shell命令

bash shell基础编程

bash内置命令

linux shell bash 内置变量参考