bash分配默认值


135

$ {parameter:= word}分配默认值。如果参数未设置或为空,则将单词的扩展分配给参数。然后替换参数的值。不能以此方式分配位置参数和特殊参数。

我以为我可以使用此功能来写代码,${LONG_VARIABLE_NAME:=hello}而不是使用更长的代码LONG_VARIABLE_NAME=${LONG_VARIABLE_NAME:-hello},但是现在bash也会尝试执行“ hello”,并且给出了未找到的命令。有什么办法可以避免这种情况?还是我必须坚持使用后者?有人可以举例说明分配默认值实际上有用吗?


13
引用文本时,包括指向源的链接会很有帮助。
Jonathon Reinhart 2015年

Answers:


201

使用冒号:

: ${A:=hello}

冒号是一个空命令,不执行任何操作,并忽略其参数。它内置在bash中,因此不会创建新进程。


93
我不禁要注意那: ${A:=hello}与一样长A=${A:-hello}。后者似乎也较不深奥,其意图更为明确。:与OP之前的操作方式相比,使用基本上是无操作的,似乎有点麻烦。
Dan Moulding

5
@camh:同意。我可以看到,如果您有很多变量可以初始化为默认值并且它们具有长名称,那么:无论是键入还是阅读,这种方法都是可取的。是的,这似乎是Bash可以改进的地方。
Dan Moulding

17
@DanMoulding:: ${VERY_LONG_VARIABLE_NAME:=hello}vs .:呢VERY_LONG_VARIABLE_NAME=${VERY_LONG_VARIABLE_NAME:-hello}?我希望您在代码中使用描述性的变量名称:)
pihentagy 2014年

18
不仅更短,而且更不容易出错:VERY_LONG_VARIABLE_NAME=${VERY_LOGN_VARIABLE_NAME:-hello}。哎呀。
chepner 2014年

5
A=$A:-hello方法的一个优点是,当与一起运行时,它可以自我记录set -x。也就是说,赋值将打印为,A=hello而null命令将仅打印值(hello)。
lmsurprenant

107

请查看http://www.tldp.org/LDP/abs/html/parameter-substitution.html的示例

${parameter-default}, ${parameter:-default}

如果未设置参数,请使用默认值。调用后,仍未设置参数。
两种形式几乎相等。:仅当声明了参数时,多余的部分才有所不同,但为null。

unset EGGS
echo 1 ${EGGS-spam}   # 1 spam
echo 2 ${EGGS:-spam}  # 2 spam

EGGS=
echo 3 ${EGGS-spam}   # 3
echo 4 ${EGGS:-spam}  # 4 spam

EGGS=cheese
echo 5 ${EGGS-spam}   # 5 cheese
echo 6 ${EGGS:-spam}  # 6 cheese

${parameter=default}, ${parameter:=default}

如果未设置参数,则将参数值设置为默认值。
两种形式几乎相等。::仅在参数已声明且为null时才起作用

# sets variable without needing to reassign
# colons suppress attempting to run the string
unset EGGS
: ${EGGS=spam}
echo 1 $EGGS     # 1 spam
unset EGGS
: ${EGGS:=spam}
echo 2 $EGGS     # 2 spam

EGGS=
: ${EGGS=spam}
echo 3 $EGGS     # 3        (set, but blank -> leaves alone)
EGGS=
: ${EGGS:=spam}
echo 4 $EGGS     # 4 spam

EGGS=cheese
: ${EGGS:=spam}
echo 5 $EGGS     # 5 cheese
EGGS=cheese
: ${EGGS=spam}
echo 6 $EGGS     # 6 cheese

${parameter+alt_value}, ${parameter:+alt_value}

如果设置了参数,则使用alt_value,否则使用空字符串。调用后,参数值未更改。
两种形式几乎相等。::仅在参数已声明且为null时才起作用

unset EGGS
echo 1 ${EGGS+spam}  # 1
echo 2 ${EGGS:+spam} # 2

EGGS=
echo 3 ${EGGS+spam}  # 3 spam
echo 4 ${EGGS:+spam} # 4

EGGS=cheese
echo 5 ${EGGS+spam}  # 5 spam
echo 6 ${EGGS:+spam} # 6 spam

20

默认值参数扩展通常在构建脚本(如下面的示例一)中很有用。如果用户仅按原样调用脚本,则不会内置perl。用户必须将其显式设置WITH_PERL为“ no”以外的其他值才能进行内置。

$ cat defvar.sh
#!/bin/bash

WITH_PERL=${WITH_PERL:-no}

if [[ "$WITH_PERL" != no ]]; then
    echo "building with perl"
    # ./configure --enable=perl
else
    echo "not building with perl"
    # ./configure
fi

不使用 Perl 构建

$ ./defvar.sh
not building with perl

Perl 编译

$ WITH_PERL=yes ./defvar.sh
building with perl
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.