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

Edw*_*ges 612 bash shell

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

if [ -z "${VARIABLE}" ]; then 
    FOO='default'
else 
    FOO=${VARIABLE}
fi
Run Code Online (Sandbox Code Playgroud)

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

FOO=${ ${VARIABLE} : 'default' }
Run Code Online (Sandbox Code Playgroud)

(虽然我知道这不起作用......)

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

And*_*gor 1098

非常接近你发布的内容,实际上:

FOO=${VARIABLE:-default}  # If variable not set or null, use default.
Run Code Online (Sandbox Code Playgroud)

或者,也将分配defaultVARIABLE:

FOO=${VARIABLE:=default}  # If variable not set or null, set it to default.
Run Code Online (Sandbox Code Playgroud)

  • 请注意,它是[*not*bash-specific](http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_02),并且可以与整个shell系列一起使用.通用脚本是安全的. (54认同)
  • 如果我想在文档中找到这个,那谷歌会是什么?使用$ {: - }这样的特殊字符进行Google搜索并不是一件容易的事. (53认同)
  • 以下是关于主题http://unix.stackexchange.com/a/122848/2407的更深入的解释 (18认同)
  • 回应solarmist:"bash变量赋值默认"让我进入这个页面,用'变量屁股'搜索bash的手册页让我在~5'下一个'之后到了正确的部分 (16认同)
  • @solarmist关键词是"bash参数扩展",如果你想了解更多关于它及其同伴的信息. (16认同)
  • 有什么区别: - 和:=? (3认同)
  • 的SubjectAltName = $ {1: - $ {SUBJECT_ALT_NAME: - $ defaultSubjectAltName}}; ...是3个替代的语法...这里第一个默认值是传递给脚本的第一个参数,否则使用env var,否则使用脚本var (3认同)
  • 这个页面有一个很好的备忘单,解释了所有这些:http://stackoverflow.com/a/16753536/5359531 (3认同)

mik*_*iku 251

对于命令行参数:

VARIABLE=${1:-DEFAULTVALUE}    
Run Code Online (Sandbox Code Playgroud)

它赋予VARIABLE传递给脚本的第一个参数的值或者DEFAULTVALUE如果没有传递这样的参数则赋值.


Han*_*zel 219

如果变量相同,那么

: "${VARIABLE:=DEFAULT_VALUE}"
Run Code Online (Sandbox Code Playgroud)

如果未定义,则将DEFAULT_VALUE分配给VARIABLE.双引号可防止通配和分词.

另请参见Bash手册中的第3.5.3节" Shell参数扩展".

  • 这个棘手的技巧对我来说并不明显,使用:无效内置来消耗$ {..}的扩展,但留下VARIABLE设置.直到现在我才这样做:VARIABLE ="$ {VARIABLE:-DEFAULT_VALUE}"并且两次使用VARIABLE感觉很笨. (21认同)
  • @Hans:冒号是命令(什么都不做)因此只需要一次.例如`:$ {FOO:= DEFAULT1} $ {BAR:= DEFAULT2}` (7认同)
  • 有机会在“export”中使用类似的东西吗?我想让这个变量可供当前脚本调用的脚本使用。 (5认同)

Ins*_*sOp 34

可以像这样链接默认值:

DOCKER_LABEL=${GIT_TAG:-${GIT_COMMIT_AND_DATE:-latest}}
Run Code Online (Sandbox Code Playgroud)

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


mon*_*lls 31

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

有一个文件 defvalue.sh

#!/bin/bash
variable1=$1
variable2=${2:-$variable1}

echo $variable1
echo $variable2
Run Code Online (Sandbox Code Playgroud)

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

first-value
second-value
Run Code Online (Sandbox Code Playgroud)

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

first-value
first-value
Run Code Online (Sandbox Code Playgroud)


gho*_*g74 26

看到这里在3.5.3(壳参数扩展)

所以在你的情况下

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


Gur*_*uru 20

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

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."
Run Code Online (Sandbox Code Playgroud)

  • 还有“{var-default}”,其中“default”仅在“var”未定义时使用。如果定义了“var”但为空,则不会使用“default”。 (5认同)
  • 为什么每一行都有一个反斜杠?其他答案没有这个。 (4认同)

Rob*_*lls 15

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

FOO='default'
[ -n "${VARIABLE}" ] && FOO=${VARIABLE}
Run Code Online (Sandbox Code Playgroud)

  • 这对于早期shell的x兼容性很有用 (4认同)
  • 这有利于与OS X bash的兼容性. (2认同)

Cur*_*oon 15

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

USERNAME=${1:?"Specify a username"}
Run Code Online (Sandbox Code Playgroud)

这会显示如下消息并退出代码1:

./myscript.sh
./myscript.sh: line 2: 1: Specify a username
Run Code Online (Sandbox Code Playgroud)

一切更完整的例子:

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

echo "$ACTION"
echo "$DIRNAME"
echo "$OUTPUT_DIR"
Run Code Online (Sandbox Code Playgroud)

输出:

$ ./script.sh foo
foo
/path/to/pwd
/tmp

$ export HOMEDIR=/home/myuser
$ ./script.sh foo
foo
/path/to/pwd
/home/myuser
Run Code Online (Sandbox Code Playgroud)
  • $ACTION 获取第一个参数的值,如果为空则退出
  • $DIRNAME 是第二个参数,默认为当前目录
  • $OUTPUT_DIR是第三个参数,或者$HOMEDIR(如果已定义),否则,/tmp.这适用于OS X,但我并不认为它是可移植的.

  • 难怪很多人不知道这些节省时间的 bash 函数。你怎样才能找到他们?bash 宏、bash 函数、bash 内置函数都无法帮助您实现这一目标。 (2认同)

Ass*_*mer 9

这是一个例子

#!/bin/bash

default='default_value'
value=${1:-$default}

echo "value: [$value]"
Run Code Online (Sandbox Code Playgroud)

将其保存为script.sh并使其可执行.没有参数运行它

./script.sh
> value: [default_value]
Run Code Online (Sandbox Code Playgroud)

用param运行它

./script.sh my_value
> value: [my_value]
Run Code Online (Sandbox Code Playgroud)


met*_*ory 6

参数替换并不总是答案 ${parameter:-default}

foo="$1"

o="${foo:-def}" # $foo, or def if unset (or null)
o="${foo:+def}" # def if $foo is set (and not null)
: "${foo:=def}" # Set $foo to def if unset (or null)
: "${foo:?msg}" # Show error message and exit if $foo is unset (or null)
Run Code Online (Sandbox Code Playgroud)
虽然默认值(右侧)可以是表达式
参数(左侧)不能是表达式

所以如果你想基于表达式进行赋值;你最终会做出某种形式的吼叫


例如

如果大于或不大于则设置oUPPERx50LOWER
# function get_o { ... }
echo "$(get_o 33)"; # LOWER
echo "$(get_o 77)"; # UPPER
Run Code Online (Sandbox Code Playgroud)

设置为整数算术条件

(( x > 50 )) && o="UPPER" || o="LOWER"
# or ..
[[ $x -ge 50 ]] && o="UPPER" || o="LOWER"
Run Code Online (Sandbox Code Playgroud)

通过命令替换设置

o="$( (( x > 50 )) && echo "UPPER" || echo "LOWER" )"
Run Code Online (Sandbox Code Playgroud)

稍后通过参数替换设置默认值

(( x > 50 )) && o="UPPER"
: "${o:=LOWER}"
Run Code Online (Sandbox Code Playgroud)

先设置默认然后更新

o="LOWER"
(( x > 50 )) && o="UPPER"
Run Code Online (Sandbox Code Playgroud)

或者使用完整的 if 语法...


Ste*_*uan 5

如果你想要 1 个 if-then-else 语句,那么我们可以考虑重写:

if [ -z "${VARIABLE}" ]; then 
    FOO='default'
else 
    FOO=${VARIABLE}
fi
Run Code Online (Sandbox Code Playgroud)

带分号:

if [ -z ${VARIABLE} ]; then FOO=`default`; else FOO=${VARIABLE}; fi
Run Code Online (Sandbox Code Playgroud)

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

[ -z "${VARIABLE}" ] && FOO='default' || FOO=${VARIABLE}
Run Code Online (Sandbox Code Playgroud)

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

conditional && then_command || else_command
Run Code Online (Sandbox Code Playgroud)