“${1-}”与“$1”相比

发布于 2024-11-02 01:48:57 字数 157 浏览 0 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

夜还是长夜 2024-11-09 01:48:57

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

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

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

First, recall that ${foo-bar} expands to the value of foo, like $foo or ${foo}, except that if foo is unset, ${foo-bar} expands to bar ($foo expands to the empty string if foo is unset). There is a more often-used variant of this syntax, ${foo:-bar}, which expands to bar if foo 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 to bar if $1 is unset, that is, if the number of positional parameters is less than 1. Unless the positional parameters have been changed with set or shift, 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 under set -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.

樱&纷飞 2024-11-09 01:48:57
echo "${foo-default}"

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

"${1-}"

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

echo "${foo-default}"

Prints $foo, if foo is defined, and 'default', if foo is undefined. So I conclude

"${1-}"

is empty, if the first argument to the script is not defined.

巡山小妖精 2024-11-09 01:48:57

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

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

${参数:-word}

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

(强调。)

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

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

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

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

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

The Bash reference manual §3.5.3 Shell Parameter Expansion says:

When not performing substring expansion, using the form described below, Bash tests
for a parameter that is unset or null. Omitting the colon results in a test only for a
parameter that is unset. Put another way, if the colon is included, the operator tests for
both parameter’s existence and that its value is not null; if the colon is omitted, the operator
tests only for existence.

${parameter:-word}

If parameter is unset or null, the expansion of word is substituted. Otherwise,
the value of parameter is substituted.

(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:

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

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'.

笑梦风尘 2024-11-09 01:48:57

原始答案

设法真正关注 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 的回答。

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:

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

$

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 in echo "${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" unless set -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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文