VARIABLE1="${VARIABLE1:-some_val}"
或一些扩展其他变量的方法
VARIABLE2="${VARIABLE2:-`echo $VARIABLE1`}"
使用这种表示法而不是直接声明值(例如
VARIABLE1=some_val
)有什么意义?这种表示法是否有好处或可以避免的错误?
:-
在这种情况下是否有特定含义?#1 楼
如果另一个变量为空或未定义,则此技术允许为变量分配值。注意:此“其他变量”可以相同或另一个变量。摘录
如果您想查看Bash中可用的所有形式的参数扩展的完整列表,那么我强烈建议您在Bash Hacker的Wiki的标题为“参数扩展”的主题中进行研究。
示例
变量不存在
${parameter:-word}
If parameter is unset or null, the expansion of word is substituted.
Otherwise, the value of parameter is substituted.
变量存在
$ echo "$VAR1"
$ VAR1="${VAR1:-default value}"
$ echo "$VAR1"
default value
通过评估其他变量或在符号的默认值部分内运行命令,可以完成同一件事。
$ VAR1="has value"
$ echo "$VAR1"
has value
$ VAR1="${VAR1:-default value}"
$ echo "$VAR1"
has value
更多示例
您还可以在
${parameter-word}
处使用略有不同的表示法。未定义,因此使用默认值VARX=${VARX-<def. value>}
。另一个示例
$ VAR2="has another value"
$ echo "$VAR2"
has another value
$ echo "$VAR1"
$
$ VAR1="${VAR1:-$VAR2}"
$ echo "$VAR1"
has another value
使用
$VAR1
表示法检查和分配最后,我会提到方便的运算符
$VAR2
。如果被测变量为空或未定义,这将进行检查并分配一个值。示例
请注意,现在已设置
$VAR3
。操作员0
只需一次操作即可完成测试和赋值。$ echo "${VAR1-0}"
has another value
$ echo "${VAR2-0}"
has another value
$ echo "${VAR3-0}"
0
但是,如果该值事先设置,则将其保留。 />
$ VARX="${VAR3-0}"
$ echo "$VARX"
0
便捷的Dandy参考表
参考文献
参数扩展-Bash黑客Wiki
10.2。参数替换
Bash参数扩展
评论
请注意,并非所有这些扩展都以bash记录。 Q中的$ {var:-word}是一个,但不是上面的$ {var-word}。 POSIX文档中有一张漂亮的表格,可能值得将其复制到此答案中-pubs.opengroup.org/onlinepubs/9699919799/utilities/…
– Graeme
2014年4月3日在1:02
@Graeme,有文档记录,您只需要注意在未设置参数的测试中省略冒号结果即可。
–StéphaneChazelas
15/12/22在11:31
如果您实际上想要回显,则使用回显“ $ {FOO:= default}”很棒。但是,如果不这样做,请尝试:内置命令...:$ {FOO:= default}您的$ FOO设置为上述默认值(即,如果尚未设置)。但是在此过程中,没有回音$ FOO。
–fbicknel
17年8月10日在19:50
好的,找到答案了:stackoverflow.com/q/24405606/1172302。使用$ {4:-$ VAR}将起作用。
– Nikos Alexandris
18年1月19日在9:23
+1仅用于详细答案。但事实上,您引用了出色的bash Wiki。还要为您提供示例和表格。地狱,一直到+1才行:)就我而言,我的语法几乎正确,但不太正确-我只是不太在意搜索手册页(不费力,但我不记得它的标题是什么)从今天早上4点起我就一直醒着:()..
–Pryftan
18年2月11日在14:43
#2 楼
@slm已经包含了POSIX文档-非常有用-但它们并没有真正扩展这些参数如何相互影响的组合。这种形式在这里还没有提及:${var?if unset parent shell dies and this message is output to stderr}
这是我的另一个答案的摘录,我认为它很好地演示了这些工作原理: br />
sh <<-\CMD
_input_fn() { set -- "$@" #redundant
echo ${*?WHERES MY DATA?}
#echo is not necessary though
shift #sure hope we have more than parameter
: ${*?WHERES MY DATA?} #: do nothing, gracefully
}
_input_fn heres some stuff
_input_fn one #here
# shell dies - third try doesnt run
_input_fn you there?
# END
CMD
heres some stuff
one
sh: line :5 *: WHERES MY DATA?
来自另一个的示例:
sh <<-\CMD
N= #N is NULL
_test=$N #_test is also NULL and
v="something you would rather do without"
( #this subshell dies
echo "v is ${v+set}: and its value is ${v:+not NULL}"
echo "So this ${_test:-"$_test:="} will equal ${_test:="$v"}"
${_test:+${N:?so you test for it with a little nesting}}
echo "sure wish we could do some other things"
)
( #this subshell does some other things
unset v #to ensure it is definitely unset
echo "But here v is ${v-unset}: ${v:+you certainly wont see this}"
echo "So this ${_test:-"$_test:="} will equal NULL ${_test:="$v"}"
${_test:+${N:?is never substituted}}
echo "so now we can do some other things"
)
#and even though we set _test and unset v in the subshell
echo "_test is still ${_test:-"NULL"} and ${v:+"v is still $v"}"
# END
CMD
v is set: and its value is not NULL
So this $_test:= will equal something you would rather do without
sh: line 7: N: so you test for it with a little nesting
But here v is unset:
So this $_test:= will equal NULL
so now we can do some other things
_test is still NULL and v is still something you would rather do without
上面的示例利用了POSIX参数的所有4种形式替换及其各种
:colon null
或not null
测试。在上面的链接中有更多信息,这里再次是。 人们通常不会考虑的关于
${parameter:+expansion}
的另一件事是,它在本文档中非常有用。这是另一个答案的摘录:TOP
这里您将设置一些默认值,并准备在调用时打印它们。
#!/bin/sh
_top_of_script_pr() (
IFS="$nl" ; set -f #only split at newlines and don't expand paths
printf %s\n ${strings}
) 3<<-TEMPLATES
${nl=
}
${PLACE:="your mother's house"}
${EVENT:="the unspeakable."}
${ACTION:="heroin"}
${RESULT:="succeed."}
${strings:="
I went to ${PLACE} and saw ${EVENT}
If you do ${ACTION} you will ${RESULT}
"}
#END
TEMPLATES
MIDDLE
在这里,您可以定义其他函数以根据其结果调用打印函数...
EVENT="Disney on Ice."
_more_important_function() { #...some logic...
[ $((1+one)) -ne 2 ] && ACTION="remedial mathematics"
_top_of_script_pr
}
_less_important_function() { #...more logic...
one=2
: "${ACTION:="calligraphy"}"
_top_of_script_pr
}
底部
现在已经完成所有设置,因此这里是执行并提取结果的地方。
_less_important_function
: "${PLACE:="the cemetery"}"
_more_important_function
: "${RESULT:="regret it."}"
_less_important_function
结果
我马上解释一下原因,但是运行上面的代码会产生以下结果:
_less_important_function()'s
第一次运行:我去了你母亲的家,在冰上看到迪斯尼。
如果你做书法,你会成功的。
然后
_more_important_function():
我去了公墓,在冰上看了迪斯尼。
如果你做补习数学,你将会成功。
/>
_less_important_function()
:我去了到墓地并在冰上看到迪斯尼。
如果进行补习数学,您会后悔的。
工作原理:
此处的主要功能是
conditional ${parameter} expansion.
的概念。仅可以使用以下形式将变量设置为未设置或为null的值:${var_name
:= desired_value}
如果只希望设置一个未设置的变量,则可以忽略
:colon
,而空值将保持不变。在范围内:
您可能会注意到,在上面的示例中,即使已调用
$PLACE
,但通过$RESULT
进行设置时,parameter expansion
和_top_of_script_pr()
也会发生变化,大概是在运行时对其进行了设置。起作用的原因是_top_of_script_pr()
是( subshelled )
函数-我将其封装在parens
中,而不是其他函数中使用的{ curly braces }
。因为它是在子外壳中调用的,所以它设置的每个变量都是locally scoped
,并在返回其父外壳时这些值消失了。但是当
_more_important_function()
设置$ACTION
时,它是globally scoped
,因此会影响_less_important_function()'s
对$ACTION
的第二次求值因为_less_important_function()
仅通过$ACTION
设置了${parameter:=expansion}.
评论
很高兴看到速记默认值在Bourne Shell中有效
– Sridhar Sarnobat
18年3月29日在4:39
#3 楼
个人经验。我有时在脚本中使用这种格式来临时覆盖值,例如如果我有:
$ cat script.sh
SOMETHING="${SOMETHING:-something}"; echo "$SOMETHING";
我可以运行:
$ env SOMETHING="something other than the default value" ./script.sh`
而不必更改原始默认值代表
SOMETHING
。
评论
看看男子扑!搜索块“ Parameter Expansion”(大约28%)。这些分配是例如默认功能:“仅在未设置默认值的情况下使用默认值。”由于:-设置默认值,如果变量不为null,则:+用于更改值。例如。 v =选项; cmd $ {v:+ with $ v}将运行“带有选项的cmd”。但是,如果$ v为null,它将仅运行“ cmd”。