14

git bash 完成的代码,特别是 function __gitcomp,使用参数扩展,如"${1-}". 这似乎类似于"$1"。有什么区别?

另外:这在bash手册中的哪里记录?

4

4 回答 4

17

首先,回想一下${foo-bar}扩展为foo、like$foo或的值${foo},除了如果foo未设置,则${foo-bar}扩展为bar(如果未设置$foo则扩展为空字符串foo)。这种语法有一个更常用的变体${foo:-bar},它扩展为bar如果foo未设置或为空。(如果您仔细观察,手册中对此进行了解释:-:搜索,并注意上面的句子“省略冒号导致仅对未设置的参数进行测试。”。)

对于位置参数$1${1-bar}扩展为bar如果$1未设置,即如果位置参数的数量小于 1。除非位置参数已用setor更改shift,这意味着当前函数,或者如果不适用则当前脚本,没有参数。

现在 whenbar是空的,${1-}看起来像一个无用的复杂化:展开是 的$1,除了 when$1未设置,展开是空的,无论如何它都会是。使用的要点${1-}是,在set -u(aka set -o nounset) 下,如果未设置参数,则纯文本$1将导致错误,而如果未设置,则${1-}始终成功扩展为空字符串$1

于 2011-04-17T15:58:34.007 回答
3
echo "${foo-default}"

如果 foo 已定义,则打印 $foo;如果 foo 未定义,则打印 'default'。所以我得出结论

"${1-}"

如果未定义脚本的第一个参数,则为空。

于 2011-04-17T11:50:50.780 回答
2

Bash 参考手册 §3.5.3 Shell Parameter Expansion 说:

当不执行子字符串扩展时,使用下面描述的形式,Bash 测试未设置或为空的参数。省略冒号会导致仅对未设置的参数进行测试。换句话说,如果包含冒号,则运算符会测试两个参数的存在以及它的值是否不为空;如果省略冒号,则运算符仅测试是否存在。

${parameter:-word}

如果参数未设置或为空,则替换单词的扩展。否则,参数的值被替换。

(强调补充。)

如果${1-}出现在 shell 脚本中的双引号内,这确实不是一种特别有用的写法"$1"。如果$1未定义,则两者"${1-}""$1"展开为空参数;如果$1已定义但为空,则它们也都扩展为空参数;否则,即使$1包含空格,它也会作为被调用程序的一个参数出现。

如果${1-}出现在双引号之外,那么它仍然没有用:如果$1未定义或为空,则被调用程序看不到参数(使用任何一种表示法);如果$1已定义,则被调用程序会根据 的(拆分)值看到一个或多个参数$1,或者如果$1仅由空格组成,则看不到任何参数。

当破折号后有某种值时,该符号真正发挥作用。例如:

localvar=${ENVVAR1:-${ENVVAR2:-/opt/software}}

这表示'如果$ENVVAR1设置为非空值(包括所有空白),请使用它;否则,查看,$ENVVAR2如果设置为非空值,请使用它;否则,使用值/opt/software'.

于 2011-04-17T15:45:45.557 回答
0

原始答案

设法真正注意手册中EXPANSION->介绍的细节。扩展案例列表( ,等)Parameter expansion之前的最后一句解释说“省略冒号会导致仅对未设置的参数进行测试。” 如果使用了,这些测试将针对未设置或 null的参数。:-:+:

所以:

$ unset malkovich
$ echo "${malkovich:-John} ${malkovich-Malkovich}"
John Malkovich
$ malkovich=
$ echo "${malkovich:-John} ${malkovich-Malkovich}"
John
$ echo "$malkovich"

$

故事的寓意:不要只扫描手册,RTFM。

附录

乍一看,这个答案似乎无关紧要;建议困惑的读者考虑 的大小写,echo "${malkovich-}"然后考虑echo "${1-}". 这是对我的问题的回答,因为它向我自己以及其他熟悉:-默认参数扩展形式的人解释了可以省略冒号。

正如 Gilles 所指出的,实际上与unless"${1-}"有效相同:在这种情况下,必须提供默认值以避免在未设置变量的情况下出现错误。有关上下文和语法的详细解释,请参阅 Johnathan Lefler 的回答。"$1"set -u

于 2011-04-17T15:16:53.337 回答