viu*_*ser 2 shell bash command-substitution
test@debian:~$ echo `echo \`echo "uh!"\``
uh!
Run Code Online (Sandbox Code Playgroud)
Bash 是如何做到这一点的?似乎它首先执行非转义反引号中的表达式,它返回(双引号“”被删除,对吗?):
`echo uh!`
Run Code Online (Sandbox Code Playgroud)
所以我们有一个输入等价于:
test@debian:~$ echo `echo uh!`
Run Code Online (Sandbox Code Playgroud)
(旁注:真的,为什么它有效?因为:
test@debian:~$ echo `echo uh!`
-bash: !`: event not found
Run Code Online (Sandbox Code Playgroud)
)
然后 Bash 再次执行反引号中的表达式,它给出:
test@debian:~$ echo uh!
Run Code Online (Sandbox Code Playgroud)
这最终给了我们输出:
uh!
Run Code Online (Sandbox Code Playgroud)
那正确吗?并且如何将四个 echo反引号表达式相互封装?
取决于您的版本bash:
bash-4.2$ echo `echo \`echo "uh!"\``
bash: !"\``: event not found
bash-4.3$ echo `echo \`echo "uh!"\``
uh!
Run Code Online (Sandbox Code Playgroud)
在bash-4.3,!"不再有资格作为历史事件指示符,因此历史扩展不适用。
除此之外,它只是普通的反引号嵌套语法。在反引号内,反斜杠字符被重载(再次)以再次执行嵌套扩展。
您可以根据需要嵌套多个级别:
echo `echo \`echo \\\`echo \\\\\\\`echo whatever\\\\\\\`\\\`\``
Run Code Online (Sandbox Code Playgroud)
这是繁琐的等价物:
echo $(echo $(echo $(echo $(echo whatever))))
Run Code Online (Sandbox Code Playgroud)
但是请注意,在两个版本中,命令替换都受分词的影响。所以,你想引用它们来防止它。
随着bash,dash,pdksh,yash,zsh,它是相对容易:
echo "`echo "\`echo "\\\`echo "\\\\\\\`echo whatever\\\\\\\`"\\\`"\`"`"
Run Code Online (Sandbox Code Playgroud)
使用 Bourne 或 Korn shell,您还需要转义"虽然,因此变为:
echo "`echo \"\`echo \\\"\\\`echo \\\\\\\"\\\\\\\`echo whatever\\\\\\\`\\\\\\\"\\\`\\\"\`\"`"
Run Code Online (Sandbox Code Playgroud)
与之比较:
echo "$(echo "$(echo "$(echo "$(echo whatever)")")")"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6263 次 |
| 最近记录: |