为什么 : 可以防止 ${username=`whoami`} 抛出错误?

3
为什么会这样?(涉及IT技术)
${username=`whoami`}

抛出一个错误,而

: ${username=`whoami`}

执行分配是否没有任何不良影响?

我了解冒号:是一个占位符。这个命令的用途是什么?是否相当于运行:'whoami'


作为参考,先前的用法被称为#3,新的用法被称为#4。


“:”是“true”,它不会对行的其余部分做任何事情 @ #4。简而言之:如果${username=whoami}没有得到您想要运行的函数/命令的名称,请不要像#3那样运行它。此时,“$()”是一个全新的子shell,这就是为什么您不能使用在其中使用的任何变量,因为它们将在该shell结束时消失。 - Wrikken
1
如果你只关心第三点和第四点的区别,那么我建议删掉其他所有内容(实际上,在这种情况下,你根本不需要一个列表)。 - Charles Duffy
完成。将列表保留为在注释中引用的内容。 - imagineerThat
我在上面进行了更广泛的重构,但保留了编号引用。 - Charles Duffy
2个回答

6
${parameter=value}

这段代码有两个作用:如果parameter尚未设置,它会将value分配给parameter;并在完成后展开parameter的值。

错误是由于直接效应引起的:当您运行该代码时,会展开parameter的值。

${user=`whoami`}

如果将变量放在单独的一行,那么它会扩展并尝试运行whoami命令的输出。假设用户变量之前未被赋值,并且whoami的输出为james,则会尝试运行james命令,这将导致错误。
相比之下,运行以下命令:
: ${user=`whoami`}

...首先会执行副作用(如果user还未设置,则会对其进行赋值),然后再运行:

: james

......这没有影响,因此只执行赋值的副作用。



我认为你使用 := 替换的原因并不明显,所以我添加了一条注释。 - imagineerThat
“:”是“true”的快捷方式。 - Edouard Thiel
@EdouardThiel,嗯...在70年代的Bourne shell中,:是一个内置命令,而true运行/bin/true,因此它们之间实际上存在效率差异。可以说,如果有人正在编写将在过时平台上运行的代码,这仍然是需要记住的事情。 - Charles Duffy
@imagineerThis,呵呵。那不是故意替换的——我习惯在自己的代码中使用:=,所以我的手指记忆就在那里——所以我已经撤回了它。 - Charles Duffy

3
在#3中,根据bash手册页面,您正在尝试执行whoami命令输出,即如果whoami命令输出为“peter”,则#3表示调用“peter”命令。此外,“username”变量被赋值为“peter”。
bash手册将${parameter:=word}描述如下:
分配默认值。如果参数未设置或为空,则将单词的扩展分配给参数。然后替换参数的值。无法以这种方式分配位置参数和特殊参数。
同样,对于:命令 -
没有效果;除了扩展参数并执行任何指定的重定向外,该命令不执行任何操作。返回零退出代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接