“$ {1-}”vs“$ 1”

时间:2011-04-17 11:43:21

标签: git bash bash-completion

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

另外:bash手册中记录了哪些内容?

4 个答案:

答案 0 :(得分:14)

首先,请回想一下${foo-bar}扩展为foo的值,例如$foo${foo},但如果foo未设置,则{{1}如果${foo-bar}未设置,则扩展为bar$foo会扩展为空字符串。此语法有一个更常用的变体foo,如果${foo:-bar}未设置或为空,则会扩展为bar。 (如果你仔细观察,这是explained in the manual:搜索foo,并在上面注意句子“省略冒号导致仅对未设置的参数进行测试。”

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

现在当shift为空时,bar看起来像一个无用的并发症:扩展是${1-}的扩展,除了未设置$1时,扩展为空,无论如何。使用$1的重点是在${1-}(又名set -u)下,如果参数未设置,则普通set -o nounset会导致错误,而$1如果未设置${1-},则始终成功扩展为空字符串。

答案 1 :(得分:3)

echo "${foo-default}"

如果定义了foo,则打印$ foo,如果未定义foo,则打印'default'。所以我总结

"${1-}"
如果未定义脚本的第一个参数,则

为空。

答案 2 :(得分:2)

Bash参考手册§3.5.3壳参数扩展说:

  

当不执行子串扩展时,使用下面描述的形式进行Bash测试   对于未设置或为null的参数。 省略冒号导致只测试a   未设置的参数。换句话说,如果包含冒号,操作员会测试   参数的存在及其值不为空;如果省略冒号,则为运算符   仅测试存在。

${parameter:-word}
     

如果参数未设置或为null,则替换单词的扩展。除此以外,   参数的值被替换。

(强调补充。)

如果${1-}出现在shell脚本的双引号内,那么写"$1"实际上并不是特别有用。如果未定义$1,则"${1-}""$1"都会展开为空参数;如果定义$1但是为空,它们也会扩展为空参数;否则,即使$1包含空格,它也会显示为被调用程序的一个参数。

如果${1-}出现在双引号之外,那么它仍然无效:如果$1未定义或为空,则被调用的程序看不到任何参数(带有任何符号);如果定义了$1,则被调用程序会根据$1的(拆分)值看到一个或多个参数,或者如果$1仅包含空格,则看不到任何参数。

当破折号之后存在某种值时,符号真正自成一体。例如:

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

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

答案 3 :(得分: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指出的那样,"${1-}"实际上与"$1"相同,除非set -u生效:在这种情况下,必须提供默认值以避免错误变量未设置的情况。请参阅Johnathan Lefler的答案,以全面解释上下文和语法。