在bash中使用单个命令为shell变量分配默认值

我在bash(3.00)外壳脚本中对变量进行了一大堆测试,如果变量未设置,则会分配默认值,例如:

if [ -z "${VARIABLE}" ]; thenFOO='default'elseFOO=${VARIABLE}fi

我似乎记得有一些语法可以在一行中执行此操作,类似于三元运算符,例如:

FOO=${ ${VARIABLE} : 'default' }

(虽然我知道这行不通……)

我疯了吗,还是有这样的事情存在?

626063 次浏览

对于命令行参数:

VARIABLE="${1:-$DEFAULTVALUE}"

它将传递给脚本的第一个参数的值分配给VARIABLE,如果没有传递这样的参数,则将DEFAULTVALUE的值分配给DEFAULTVALUE。引用防止全局和单词拆分。

实际上非常接近你发布的内容。你可以使用名为bash参数扩展的东西来完成此操作。

要获取分配的值,如果缺少,则为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.

参见3.5.3下的这里(shell参数扩展)

所以在你的情况下

${VARIABLE:-default}

然后是更简洁地表达你的if结构的方法:

FOO='default'[ -n "${VARIABLE}" ] && FOO=${VARIABLE}

即使您可以使用默认值另一个变量的值

有一个文件defvalue.sh

#!/bin/bashvariable1=$1variable2=${2:-$variable1}
echo $variable1echo $variable2

运行./defvalue.sh first-value second-value输出

first-valuesecond-value

./defvalue.sh first-value输出

first-valuefirst-value

如果变量相同,则

: "${VARIABLE:=DEFAULT_VALUE}"

如果未定义,则将DEFAULT_VALUE分配给VARIABLE

  • 结肠内置素:)确保变量结果不被执行
  • 双引号(")可以防止全局输入和单词拆分。

另请参阅Bash手册中的第3.5.3节,外壳参数扩展

这里有一个例子

#!/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]

FWIW,您可以提供如下错误消息:

USERNAME=${1:?"Specify a username"}

这将显示这样的消息并以代码1退出:

./myscript.sh./myscript.sh: line 2: 1: Specify a username

一个更完整的例子:

#!/bin/bashACTION=${1:?"Specify 'action' as argv[1]"}DIRNAME=${2:-$PWD}OUTPUT_DIR=${3:-${HOMEDIR:-"/tmp"}}
echo "$ACTION"echo "$DIRNAME"echo "$OUTPUT_DIR"

输出:

$ ./script.sh foofoo/path/to/pwd/tmp
$ export HOMEDIR=/home/myuser$ ./script.sh foofoo/path/to/pwd/home/myuser
  • $ACTION获取第一个参数的值,如果为空则退出
  • $DIRNAME是第二个参数,默认为当前目录
  • $OUTPUT_DIR是第三个参数,或者$HOMEDIR(如果定义),否则,/tmp。这在OS X上有效,但我不确定它是可移植的。

回答你的问题和所有变量替换

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}"

可以像这样链接默认值:

DOCKER_LABEL=${GIT_TAG:-${GIT_COMMIT_AND_DATE:-latest}}

即如果$GIT_TAG不存在,取$GIT_COMMIT_AND_DATE-如果这不存在,取"latest"

如果你想要1行为您的if-then-ther,那么我们可以考虑重写:

if [ -z "${VARIABLE}" ]; thenFOO='default'elseFOO=${VARIABLE}fi

用分号:

if [ -z ${VARIABLE} ]; then FOO=`default`; else FOO=${VARIABLE}; fi

或者,如果您使用布尔运算符,您可以删除if-then-else-fi关键字,例如:

[ -z "${VARIABLE}" ] && FOO='default' || FOO=${VARIABLE}

概括起来,布尔运算符模式是:

conditional && then_command || else_command