ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

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

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

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

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

bash shell 参考的 Shell Parameter Expansion 部分是一个很好的起点:tiswww.case.edu/php/chet/bash/bashref.html#Shell-Expansions
Shell Parameter Expansion 的 Gnu.org 文档(提示:您还可以做很多其他很酷的事情!)

M
Matthias Braun

实际上,非常接近您发布的内容。您可以使用名为 Bash parameter expansion 的东西来完成此操作。

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

如果我想在文档中找到这个,谷歌会做什么?使用 ${:-} 等特殊字符进行谷歌搜索并不容易。
作为对 solarmist 的回应:“bash variable assignment default”让我进入这个页面,并在 ~5 'next' 之后使用“variable ass”搜索 bash 的手册页让我进入了正确的部分
请注意,它是 not bash-specific,适用于整个 shell 系列。对于通用脚本来说是安全的。
@solarmist 关键字是“bash 参数扩展”,如果您想了解更多关于它及其同伴的信息。
以下是关于主题 unix.stackexchange.com/a/122848/2407 的更深入解释
H
Hans Ginzel

对于命令行参数:

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

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


D
David Cook

如果变量相同,则

: "${VARIABLE:=DEFAULT_VALUE}"

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

内置冒号 (:) 确保不执行变量结果

双引号 (") 可防止通配符和分词。

另请参阅 Bash 手册中的第 3.5.3 节,Shell Parameter Expansion


这个棘手的技巧对我来说并不明显,使用 : no-effect builtin 来吃 ${..} 的扩展,但留下 VARIABLE 集。到目前为止,我一直在这样做: VARIABLE="${VARIABLE:-DEFAULT_VALUE}" 并且因为使用 VARIABLE 两次而感到愚蠢。
事实证明,这并不总是适用于 BASH 内置变量。这非常非常奇怪。目前我知道的是HISTTIMEFORMAT
我将如何设置多个默认值?我试过 ": ${VARIABLE:=DEFAULT_VALUE} : ${VARIABLE2:=DEFAULT_VALUE2}" 但这似乎不起作用......
@Hans:冒号是命令(什么都不做),因此只需要一次。例如: ${FOO:=DEFAULT1} ${BAR:=DEFAULT2}
有机会在 export 中使用类似的东西吗?我想让这个变量可用于从当前脚本调用的脚本。
P
Pierre-Antoine Guillaume

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

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

还有 {var-default},其中 default 仅在 var 未定义时使用。如果定义了 var 但为 null,则不会使用 default
为什么每行都有一个反斜杠?其他答案没有。
M
Montells

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

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

C
Clément

见3.5.3(shell参数扩展)下的here

所以在你的情况下

${VARIABLE:-default}

C
Curtis Mattoon

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,但我不肯定它是可移植的。


R
Rob Wells

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

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

A
Assaf Shomer

这是一个例子

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

I
InsOp

可以像这样链接默认值:

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

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