在反引号扩展中使用xargs,而不是替换输入字符串

时间:2017-03-27 14:03:56

标签: shell sed xargs backticks

echo "who are you" | xargs -i@ echo `echo @ | sed "s/who/where/"`

预期输出

where are you

实际输出

who are you

注意 - 这不是实际用例,而是示例测试用例。

2 个答案:

答案 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>