“${1-}”与“$1”相比
git bash 完成的代码,特别是函数 __gitcomp
,使用像 "${1-}"
这样的参数扩展。这看起来与 "$1"
类似。有什么区别?
另外:bash
手册中记录了这一点?
The code for git bash completion, specifically the function __gitcomp
, uses parameter expansions like "${1-}"
. This appears to be similar to "$1"
. What is the difference?
Also: where is this documented in the bash
manual?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
首先,回想一下
${foo-bar}
扩展为foo
的值,例如$foo
或${foo}< /code>,但如果
foo
未设置,则${foo-bar}
扩展为bar
($foofoo
未设置,> 将扩展为空字符串)。此语法有一个更常用的变体,${foo:-bar}
,如果foo
未设置或未设置,则它会扩展为bar
空的。 (手册中对此进行了解释,如果您仔细观察:搜索:-
,并注意句子“省略冒号只会对上面未设置的参数进行测试。)对于位置参数
$1,如果未设置
$1
,即位置参数的数量小于 1,则${1-bar}
扩展为bar
。除非位置参数已通过set
或shift
更改,这意味着当前函数(或当前脚本(如果不适用))没有参数。现在,当
bar
为空时,${1-}
看起来像是一个无用的复杂化:扩展是$1
的扩展,除了当>$1
未设置,扩展是空的,无论如何它都会是空的。使用${1-}
的要点在于,在set -u
(又名set -o nounset
)下,一个普通的$1如果未设置参数,
将导致错误,而如果未设置$1
,则${1-}
始终成功扩展为空字符串。First, recall that
${foo-bar}
expands to the value offoo
, like$foo
or${foo}
, except that iffoo
is unset,${foo-bar}
expands tobar
($foo
expands to the empty string iffoo
is unset). There is a more often-used variant of this syntax,${foo:-bar}
, which expands tobar
iffoo
is unset or empty. (This is explained in the manual if you look closely enough: search for:-
, and note the sentence “Omitting the colon results in a test only for a parameter that is unset.” above.)For a positional parameter
$1
,${1-bar}
expands tobar
if$1
is unset, that is, if the number of positional parameters is less than 1. Unless the positional parameters have been changed withset
orshift
, this means that the current function, or if not applicable the current script, has no parameter.Now when
bar
is empty,${1-}
looks like a useless complication: the expansion is that of$1
, except that when$1
is unset, the expansion is empty, which it would be anyway. The point of using${1-}
is that underset -u
(a.k.a.set -o nounset
), a plain$1
would result in an error if the parameter was unset, whereas${1-}
always successfully expands to the empty string if$1
is unset.如果 foo 已定义,则打印 $foo;如果 foo 未定义,则打印 'default'。所以我的结论
是,如果脚本的第一个参数未定义,则为空。
Prints $foo, if foo is defined, and 'default', if foo is undefined. So I conclude
is empty, if the first argument to the script is not defined.
Bash 参考手册 §3.5.3 Shell 参数扩展 说:
(强调。)
如果
${1-}
出现在 shell 脚本中的双引号内,那么这实际上并不是一种特别有用的编写"$1"
的方式。如果未定义$1
,则"${1-}"
和"$1"
都会扩展为空参数;如果$1
已定义但为空,则它们也会扩展为空参数;否则,即使$1
包含空格,它也会作为被调用程序的一个参数出现。如果
${1-}
出现在双引号之外,那么它仍然没有用:如果$1
未定义或为空,则被调用的程序看不到任何参数(任一符号);如果定义了$1
,那么被调用的程序会根据$1
的(分割)值看到一个或多个参数,或者如果$1< /code> 仅由空格组成。
当破折号后面有某种值时,这种符号才真正发挥作用。例如:
这表示“如果
$ENVVAR1
设置为非空值(包括所有空格),则使用它;否则,查看 $ENVVAR2 ,如果它设置为非空值,则使用它;否则,使用值/opt/software
'。The Bash reference manual §3.5.3 Shell Parameter Expansion says:
(Emphasis added.)
If the
${1-}
appears inside double quotes in the shell script, it is really a not particularly useful way of writing"$1"
. If$1
is not defined, then both"${1-}"
and"$1"
expand to an empty argument; if$1
is defined but empty, they also both expand to an empty argument; and otherwise, even if$1
contains spaces, it appears as one argument to the called program.If the
${1-}
appears outside double quotes, then it still isn't useful: if$1
is undefined or empty, then the called program sees no argument (with either notation); if$1
is defined, then the called program sees one or more arguments based on the (split up) value of$1
, or it sees no argument if$1
consists only of white space.The notation really comes into its own when there is a value of some sort after the dash. For example:
This says 'if
$ENVVAR1
is set to a non-empty value (including all blanks), use it; otherwise, look at$ENVVAR2
and if it is set to a non-empty value, use it; otherwise, use the value/opt/software
'.原始答案
设法真正关注
EXPANSION
介绍的细节 ->手册中的参数扩展
。扩展案例列表(:-
、:+
等)之前的最后一句解释说“省略冒号会导致仅对未设置的参数进行测试” ”。如果使用:
,这些测试将针对未设置或 null 的参数。所以:
这个故事的寓意是:不要只浏览手册,RTFM。
附录
乍一看,这个答案似乎无关紧要;建议困惑的读者考虑
echo "${malkovich-}"
的情况,然后考虑echo "${1-}"
中使用的原始形式。这是对我的问题的回答,因为它向我自己以及熟悉默认参数扩展的:-
形式的其他人解释了可以省略冒号。正如 Gilles 指出的,
"${1-}"
实际上与"$1"
相同,除非set -u
有效:在这种情况下,有必要提供默认值,以避免在未设置变量的情况下出现错误。有关上下文和语法的完整解释,请参阅 Johnathan Lefler 的回答。original answer
Managed to actually pay attention to the detail of the intro to
EXPANSION
->Parameter expansion
in the manual. The final sentence before the list of expansion cases (:-
,:+
, etc.) explains that "Omitting the colon results in a test only for a parameter that is unset." If the:
is used, those tests will be for a parameter that is either unset or null.So:
Moral of the story: don't just scan the manual, RTFM.
appendix
At first glance, this answer may seem irrelevant; confused readers are advised to consider the case of
echo "${malkovich-}"
and then the original form as used inecho "${1-}"
. This is an answer to my question in that it explains to myself, as well as others familiar with the:-
form of default parameter expansion, that the the colon can be omitted.As Gilles points out,
"${1-}"
is effectively the same as"$1"
unlessset -u
is in effect: in that case, the provision of a default value is necessary to avoid an error in cases where the variable is unset. See Johnathan Lefler's answer for a thorough explanation of the context and syntax.