echo "who are you" | xargs -i@ echo `echo @ | sed "s/who/where/"`
预期输出:
where are you
实际输出:
who are you
注意 - 这不是实际用例,而是示例测试用例。
答案 0 :(得分:1)
必须稍微修改扩展顺序:
echo "who are you" | echo "`sed "s/who/where/"`" | xargs -I@ echo "@"
在您的示例中,命令替换发生在shell启动命令之前:
echo "who are you" | xargs -i@ echo `echo @ | sed "s/who/where/"`
命令替换执行此操作:
echo @ | sed "s/who/where/"
结果是"@"
,因为sed只打印输入。
下一步是:
echo "who are you" | xargs -i@ echo @
xargs用标准输入“你是谁”替换@
并构建并运行此命令:
echo "who are you"
最后你得到了输出:
who are you
答案 1 :(得分:1)
我假设实际用例确实需要xargs
; 示例命令最简单的重新制定只是echo 'who are you' | sed 's/who/where/'
要获得预期的行为,xargs
必须使用包含shell命令的字符串显式调用shell二进制文件sh
:
$ echo "who are you" | xargs -I@ sh -c 'echo "$1" | sed "s/who/where/"' - @
where are you
正如twalberg所指出的那样,在你的尝试中,{/ 1}}内的命令在 `...`
运行之前被评估为,并且它会导致 literal xargs
(由于将文字 @
传递给@
,它只输出echo
,因为{{1} }命令找不到要替换的内容),@
然后简单地将其输入替换为;正如twalberg所说:你有效地运行了
sed
,一个虚拟的无操作,除了可能修剪前导和尾随空格外。
通常,xargs
只能调用外部实用程序,如果需要一个需要 shell 功能的命令(如管道),则必须显式调用shell二进制文件一个包含shell命令的单字符串 - 即一个特殊脚本 - 在echo 'who are you' | xargs -i@ echo @
调用时由该shell实例进行评估。
xargs
使用指定的脚本(包含shell命令的字符串)调用xargs
进行评估,并且通过{{1}最安全}}'参数作为该脚本的位置参数;请注意脚本绑定到sh -c
后的第一个参数,因此使用虚拟值/bin/sh
,后跟xargs
,{{1}替换字符串,其扩展值将绑定到脚本中的$0
。
_
充当ad-hoc shell脚本,将其第一个位置参数 - @
传递的参数 - 传递给xargs
以产生所需的输出。 / p>