bash指定默认值

zed*_*doo 120 bash

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

我以为我可以使用这个功能来${LONG_VARIABLE_NAME:=hello}代替更长的时间LONG_VARIABLE_NAME=${LONG_VARIABLE_NAME:-hello},但是现在bash也试图执行'hello'并且给出了一个找不到的命令.有什么办法可以避免吗?或者我必须坚持后者?有人可以给出一个分配默认值实际有用的例子吗?

cam*_*amh 184

使用冒号:

: ${A:=hello}
Run Code Online (Sandbox Code Playgroud)

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

  • 我不禁要注意到`:$ {A:= hello}`与`A = $ {A:-hello}`完全一样长.后者似乎也不那么深奥,其意图更加清晰.使用`:`,这基本上是一个无操作,与之前OP的做法相比,看起来像kludgy. (82认同)
  • 不仅更短,而且更不容易出错:'VERY_LONG_VARIABLE_NAME = $ {VERY_LOGN_VARIABLE_NAME:-hello}`.哎呀. (18认同)
  • @DanMoulding:怎么样`:$ {VERY_LONG_VARIABLE_NAME:= hello}`vs.:'VERY_LONG_VARIABLE_NAME = $ {VERY_LONG_VARIABLE_NAME:-hello}`.我希望你在代码中使用描述性变量名:) (15认同)
  • @camh:同意.我可以看到,如果你有很多变量要初始化为默认值并且它们有长名称,那么`:`方法可以优先用于打字和阅读.是的,这似乎是Bash可以使用一点改进的领域. (5认同)
  • @DanMoulding:我认为这两种解决方案都不令人满意。我不喜欢第二种形式的口吃,所以我稍微喜欢在脚本开头运行`:` 行来设置默认值。(此外,对于单字符变量名称,它们的长度仅相同)。 (3认同)
  • A = $ A:-hello方法的优点在于,当与set -x运行时,它是自记录的。也就是说,赋值将打印为“ A = hello”,而null命令将仅打印值(“ hello”)。 (3认同)
  • 只有此格式可以与位置参数一起使用:`${1:-2}`。 (2认同)

Jon*_*n L 88

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

${parameter-default}, ${parameter:-default}
Run Code Online (Sandbox Code Playgroud)

如果未设置参数,请使用默认值.通话后,参数仍未设置.
两种形式几乎相同.:只有在声明参数时,extra 才会有所不同,但是为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
Run Code Online (Sandbox Code Playgroud)
${parameter=default}, ${parameter:=default}
Run Code Online (Sandbox Code Playgroud)

如果未设置参数,请将参数值设置为默认值.
两种形式几乎相同.:仅在声明参数且为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
Run Code Online (Sandbox Code Playgroud)
${parameter+alt_value}, ${parameter:+alt_value}
Run Code Online (Sandbox Code Playgroud)

如果参数设置,请使用alt_value,否则使用null字符串.通话后,参数值没有改变.
两种形式几乎相同.:仅在声明参数且为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
Run Code Online (Sandbox Code Playgroud)


Sie*_*geX 18

默认值参数扩展通常在构建脚本中很有用,如下面的示例一样.如果用户只是按原样调用脚本,则不会内置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
Run Code Online (Sandbox Code Playgroud)

没有 Perl 构建

$ ./defvar.sh
not building with perl
Run Code Online (Sandbox Code Playgroud)

使用 Perl 构建

$ WITH_PERL=yes ./defvar.sh
building with perl
Run Code Online (Sandbox Code Playgroud)

  • 问题是关于“分配默认值”语法(`:=`),而不是“使用默认值”语法(`:-`)。 (2认同)