当我输入
echo $HOME/Downloads | xargs cd
它正确地将目录更改为 $HOME/Downloads。可能是因为在管道传输到 之前echo
进行了评估。$HOME
xargs
但是如果我输入
echo '$HOME/Downloads' | xargs cd
$HOME/Downloads
按原样传递xargs
,但无法更改目录。它给出错误:
/usr/bin/cd:第 4 行:cd:$HOME/Downloads:没有此文件或目录
所以我的问题是是否可以xargs
评估$HOME
,如果可以如何评估。
答案1
Bash 变量只能由 bash shell 评估。
当您echo '$HOME/dir'
将结果通过管道传输到另一个命令时,您就是在告诉 bash 不要评估变量并将参数视为字符串。
xargs(和大多数其他命令)没有 bash 变量的概念 - 它们需要调用 bash shell 来评估它们。例如:
echo '$HOME/dir' | xargs bash -c cd
这将调用一个 bash shell,它会评估变量并 cd 到正确的目录中。但是,完成后,shell 将终止并将控制权返回给原始 shell(它仍然在起始目录中)。
因此它可以起作用,但可能不是你想要的那样。
答案2
Paul 的解释是正确的。以下我的回复是在 Anurag Peshne 向我重新解释他的意思之前写的,请参阅下面的评论。我保留我的回复,尽管它与主题无关,因为在我看来,隐藏我的错误是懦弱的表现。
表达式不是按照原始 OP 的意愿工作,包含:
echo '$HOME/Downloads'
即单引号内的 shell 变量。''这是标准的 bash shell 术语,不计算单引号内的表达式。 实际上,
$ echo '$HOME/Downloads'
$HOME/Downloads
$ echo "$HOME/Downloads"
/home/myname/Downloads
''请注意使用单引号和双引号之间的区别" ",它们的意思是:替换变量。
事实上,Bash 手册对这种差异有如下解释:
将字符括在单引号 (''') 中可保留引号内每个字符的字面值。单引号之间不能出现单引号,即使前面有反斜杠。
将字符括在双引号 ('"') 中会保留引号内所有字符的文字值,但 '$'、'`'、'\' 和启用历史扩展时的 '!' 除外。字符 '$' 和 '`' 在双引号内保留其特殊含义(请参阅 Shell 扩展)。反斜杠仅在后跟以下字符之一时才保留其特殊含义:'$'、'`'、'"'、'\' 或换行符。在双引号内,后跟这些字符之一的反斜杠将被删除。前面没有特殊含义的字符的反斜杠保持不变。双引号内可以通过在双引号前面加上反斜杠来引用双引号。如果启用,除非使用反斜杠对双引号中出现的 '!' 进行转义,否则将执行历史扩展。'!' 前面的反斜杠不会被删除。
特殊参数 '*' 和 '@' 在双引号中时具有特殊含义(参见 Shell 参数扩展)。
简而言之,OP 显示的命令与 Bash 手册中所述完全相同,并且整个过程与参数。