众所周知,export
masks the return value of command
substitutions in its variable assignments。但是,有趣的是
export
不会不掩盖失败替换的返回值:
$ (set -eu; export FOO="$(bad_command)"); echo $?
bash: bad_command: command not found
0
$ (set -eu; export FOO="${bad_variable}"); echo $?
bash: bad_variable: unbound variable
1
$ (set -eu; export FOO="${}"); echo $? # bad substitution
bash: ${}: bad substitution
1
(dash
中的类似行为。)
规范的哪一部分表示命令失败
替代不会通过export
传播,但会失败
参数扩展吗?
man bash
(GNU Bash 4.4)中的相关部分:
set -u
处理未设置的变量和参数,而不是 特殊参数“ @”和“ *”作为执行参数时的错误 扩张。如果尝试对未设置的变量进行扩展,或者 参数,外壳程序会显示一条错误消息,如果不是交互式的, 以非零状态退出。
和
export [-fn] [name[=word]] ... export -p
提供的
names
被标记为自动导出到 后续执行命令的环境。如果-f
选项是 给定的名称是指功能。如果没有给出名称,或者 提供了-p
选项,所有导出变量的名称列表为 印刷。-n
选项导致从中删除导出属性 每个name
。如果变量名后跟=word
,则值 变量设置为word
。export
返回退出状态0 除非遇到无效的选项,否则names
之一不是 有效的shell变量名称,或者-f
附带了name
不是功能。
-我在这里看不到任何可以区分这两种情况的内容。
具体来说,export
只是说变量“的值已设置
到“ word
”,这表明它经历了正常的扩展
处理(确实如此)而无需特殊处理。
POSIX规范参考:
答案 0 :(得分:2)
这两种情况都不完全符合export
命令替换只是变成命令参数数组中的文本(是否为空)。 Unix流程模型没有任何机制来中继文本是否来自程序,或者该程序是否成功。
这意味着在运行foo var="$(true)"
vs foo var="$(false)"
vs foo var=""
时,编写外部命令的行为是不可能的,并且像export
这样的shell内置程序通常遵循相同的命令行为以便于实施。
使用set -u
和未设置的变量,该命令根本不会运行。如果在构建参数数组时遇到此条件,则外壳程序仅跳过执行,而是报告失败。命令从未选择忽略这种失败,因为从未咨询过它。
如果在参数数组的构造过程中命令替换失败,则可以实现一种新的shell模式,该模式类似地跳过执行并报告失败,但这不是传统功能,因此不在POSIX规范中。 / p>