MS.*_*Kim 8 shell-script terminology
在 shell 编程语言中,扩展和替换似乎可以在相同的上下文中互换。例如,Bash 参考手册、Bash Hackers Wiki等一些文档使用“扩展”一词来解释“shell 参数扩展”。然而,其他一些文件似乎更喜欢“替代”这个词。Advanced Bash-Scripting Guide使用参数替换。
在 shell 编程术语方面,“扩展”和“替换”之间有什么区别吗?
在这种情况下,替代几乎与扩展同义,因为它们的含义重叠。两者都不是另一个完整的子类别,尽管在您参考的GNU 手册部分中,有一些替换被视为整体扩展的一部分。
的膨胀被提取标识符的值。例如,如果this=that,当我们展开this我们得到that。不涉及替换的扩展是预先确定的,因为使用的值已经存在并且必须简单地检索,尽管这包括组合检索/显式值(例如使用“算术扩展”)。
甲替代产生一个值作为一个明确的输入/输出操作的结果。例如,如果this=$(foo bar),this是执行的结果foo bar和捕获其输出。1虽然替换产生的值可能完全可以预测,但它与正常扩展中检索到的值不同,因为它在替换发生之前实际上并不存在——它被产生。
替换有两种风格,command和process,它们有点对称:
# Command substitution
foo=$(ls)
# Process substitution
wc <(ls)
Run Code Online (Sandbox Code Playgroud)
第一个中的“命令”是ls,第二个中的“过程”也是。我们可能会说被替换的东西实际上是管道的末端。进程替换与重定向重叠。然而,这在技术上可能有点过于底层限制,这让我们进入了脚注......
foo bar在这种情况下可能是一个内部 shell 函数,在这种情况下它没有进程间 IO。shell 内置函数的存在不太明显地掩盖了这种差异。在内容方面,输入和输出将是相同的。 set -- arg arg2
echo ${2+"$1"}
#OUTPUT
arg
shift
echo ${2+"$1"}
#OUTPUT
#there doesn't seem to be anything hereRun Code Online (Sandbox Code Playgroud)
我认为这种差异一般来说太小了,不值得注意——而且这些术语经常可以互换使用。不过,如果你看一下上面的两个例子,你会发现在第一个例子中,我们将 替换 $1为的扩展$2结果。一旦无法扩展,就没有替代品。$2$2
《金发姑娘》很好地阐述了替代品的虚无缥缈的存在。我猜有点像薛定谔的猫。这让我想起一件事。您可能不熟悉这种形式的 POSIX 指定的参数扩展,但它的工作方式与上述形式相反:
${var:?if $var is unset or null its \
parent shell dies and this message is output to stderr}
Run Code Online (Sandbox Code Playgroud)
现在有时我想要相同的行为,但有一个set值。POSIX 没有明确指定任何事物的行为。但是,通过一两个技巧,它就可以轻松管理:
N= #N is null
var="any value should fail"
${var:+${N:?we substitute our \$Null var when \$var is expanded}}
#OUTPUT
sh: line 3: N: we substitute our $Null var when $var is expanded
Run Code Online (Sandbox Code Playgroud)
但:
N= #N is null
var=
${var:+${N:?is never substituted}}
#OUTPUT
#there doesn't seem to be anything here
Run Code Online (Sandbox Code Playgroud)