为什么 subshell returns if: command not found
why does subshell returns if: command not found
让我们假设以下脚本:
echo "if test 1 -eq ; then echo ls;fi" | tee /tmp/toto
cat /tmp/toto
$(cat /tmp/toto)
同时 运行使用此命令对其进行设置:
./non_secure_script 1
我收到以下错误:
if: command not found
但是,下面的命令运行成功了:
$(if test 1 -eq 1; then echo ls;fi)
为什么会这样?
因为大多数解析 traditional/standard(即不是 *csh、rc 等)shell 输入,特别是识别像 if
这样的保留字和像 [=11= 这样的复合命令] 在 扩展如 $( command )
之前完成。请参阅页面后面的 sequence defined by POSIX,特别是步骤 2 和 3 以及第 2.2-2.4 节,而页面后面的步骤 4 和第 2.5-2.6 节,不是 'wordexp' 作为链接 (!!!).
如果您在 shell 上执行 $(/tmp/toto)
或 $(. /tmp/toto)
- 或 $(source /tmp/toto)
作为同义词 - 它会 执行 子 shell 和 return 中的 if 构造到主 shell 只有字符串 ls
(或什么都没有)。由于主 shell 已将其解析为简单命令(请参阅上面链接页面上的第 2.9.1 节)before 扩展,并且 ls
是有效的simple-command,执行成功。因为分词和路径名扩展(通常称为 globbing)是作为 2.6 节中扩展的最后步骤完成的(除非禁用),returning 一个包含多个 space 分隔词的字符串,例如 ls -la
会起作用,除非它们包含像 ?
或 *
这样的 glob 运算符,但像 ls -la 'file with spaces'
这样的引用不起作用。
你的第二个案例 $(if...fi)
出于同样的原因工作;它在子 shell 和 return 中执行 if-construct 仅 ls
在主 shell 中执行,这是一个有效的简单命令。
让我们假设以下脚本:
echo "if test 1 -eq ; then echo ls;fi" | tee /tmp/toto
cat /tmp/toto
$(cat /tmp/toto)
同时 运行使用此命令对其进行设置:
./non_secure_script 1
我收到以下错误:
if: command not found
但是,下面的命令运行成功了:
$(if test 1 -eq 1; then echo ls;fi)
为什么会这样?
因为大多数解析 traditional/standard(即不是 *csh、rc 等)shell 输入,特别是识别像 if
这样的保留字和像 [=11= 这样的复合命令] 在 扩展如 $( command )
之前完成。请参阅页面后面的 sequence defined by POSIX,特别是步骤 2 和 3 以及第 2.2-2.4 节,而页面后面的步骤 4 和第 2.5-2.6 节,不是 'wordexp' 作为链接 (!!!).
如果您在 shell 上执行 $(/tmp/toto)
或 $(. /tmp/toto)
- 或 $(source /tmp/toto)
作为同义词 - 它会 执行 子 shell 和 return 中的 if 构造到主 shell 只有字符串 ls
(或什么都没有)。由于主 shell 已将其解析为简单命令(请参阅上面链接页面上的第 2.9.1 节)before 扩展,并且 ls
是有效的simple-command,执行成功。因为分词和路径名扩展(通常称为 globbing)是作为 2.6 节中扩展的最后步骤完成的(除非禁用),returning 一个包含多个 space 分隔词的字符串,例如 ls -la
会起作用,除非它们包含像 ?
或 *
这样的 glob 运算符,但像 ls -la 'file with spaces'
这样的引用不起作用。
你的第二个案例 $(if...fi)
出于同样的原因工作;它在子 shell 和 return 中执行 if-construct 仅 ls
在主 shell 中执行,这是一个有效的简单命令。