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


680

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

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

我似乎想起了在一行中执行此操作的某种语法,类似于三元运算符,例如:

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

(尽管我知道那行不通...)

我疯了还是存在类似的东西?


1
bash shell参考的“ Shell参数扩展”部分是一个很好的起点:tiswww.case.edu/php/chet/bash/bashref.html#Shell-Expansions
Kemin Zhou

1
Gnu.org Shell参数扩展文档(提示:您还可以做很多其他很酷的事情!)
JDB仍然记得Monica

Answers:


1222

实际上与您发布的内容非常接近:

FOO=${VARIABLE:-default}  # If variable not set or null, use default.

或者,这也将分配defaultVARIABLE

FOO=${VARIABLE:=default}  # If variable not set or null, set it to default.

64
如果我想在文档中找到它,那么Google会做什么?使用$ {:-}之类的特殊字符进行搜索并不容易。
约书亚·奥尔森

20
回应solarmist:“ bash变量赋值默认值”让我进入此页面,并在bash的手册页中使用“变量ass”进行搜索,使我到达
〜5'next

57
请注意,它不是特定于bash的,并且可以与整个shell系列一起使用。对于通用脚本来说是安全的。
Jocelyn delalande 2014年

16
@solarmist如果要查找有关它及其配套对象的更多信息,则关键字为“ bash参数扩展”。
duleshi 2014年


288

对于命令行参数:

VARIABLE=${1:-DEFAULTVALUE}    

它分配给VARIABLE传递给脚本的第一个参数的值,或者赋给DEFAULTVALUE没有传递此类参数的值。


243

如果变量相同,则

: "${VARIABLE:=DEFAULT_VALUE}"

如果未定义,则将DEFAULT_VALUE分配给VARIABLE。双引号可防止出现乱码和单词拆分。

另请参阅Bash手册中的第3.5.3节“ Shell参数扩展”


27
使用::no-effect内置函数吃掉$ {..}的扩展但设置了VARIABLE的扩展,这个棘手的技巧对我来说并不明显。到现在为止,我一直在这样做:VARIABLE =“ $ {VARIABLE:-DEFAULT_VALUE}”并且由于两次使用VARIABLE而感到很生气。
恐龙

事实证明,这对于BASH-BUILTIN变量始终无效。非常非常奇怪。目前我所知道的是HISTTIMEFORMAT
Otheus

如何设置多个默认值?我尝试了“:$ {VARIABLE:= DEFAULT_VALUE}:$ {VARIABLE2:= DEFAULT_VALUE2}”,但这似乎不起作用...
Hans

8
@Hans:冒号是命令(不执行任何操作),因此仅需要一次。EG: ${FOO:=DEFAULT1} ${BAR:=DEFAULT2}
帕特里克

34

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

有文件 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


25

回答您的问题以及所有变量替换

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

17

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上使用,但我不确定它是否可移植。

16

然后有一种方法可以更简洁地表达“ if”结构:

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

9

这是一个例子

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