2017-08-09 47 views
1

由于问题本身令人困惑,标题有点混淆。如何逃离嵌套bash命令返回的空间

先决条件:

我使用这个脚本script.sh作为传递的参数游乐场:

#!/bin/bash 

echo $1 
echo $2 
echo $3 

问题:

我希望这一呼吁

./script.sh $(echo "foo \"bar baz\"") 

的行为究竟如

./script.sh foo "bar baz" 

相应地,我期望能获得

foo 
bar baz 

的输出结果,但它返回

foo 
"bar 
baz" 

很显然,我需要逃避的东西。我怀疑这是一个空间,但我不确定。

问题:嵌套echo呼叫看起来应该像这样,外部呼叫收到2个参数

PS:这是一个比较复杂脚本的简化,但原来的呼叫的主要问题是保持。

回答

2

你不能这样做。不管$(somecommand)将被视为数据,而不是解释为shell语法,因此它中的任何引号和转义将被简单地视为常规字符。这是你所看到的 - echo打印的双引号被视为./script.sh的参数的一部分,而不是作为分隔符大约的论点。

另一种考虑这种情况的方法是shell在分析命令行时所经历的过程。这里有一个高度简化的总结:

  1. 解析命令行,包括引号和转义。请注意,在此过程中,引号和转义将被删除。
  2. 展开类似变量($var)和命令替换($()和反引号的命令)。
  3. 对这些扩展的结果执行分词和通配符扩展(除非它们来自步骤1的双引号)。

请注意,任何变量扩展或命令替换的结果都是命令行的一部分时,quote和escape解析已完成; shell不会将这些处理应用于这些扩展的结果。

现在,根据你实际要做的事情,可能有另一种方法来实现它。例如,可以使用readxargs来分割字符串,同时尊重其中的引号/转义字符。还有eval,但要尽可能地避免这种情况发生 - 它具有当之无愧的臭虫磁铁的声誉。

+0

是的,我认为'echo“foo \”bar baz \“”| xargs。/ script.sh'是所有选项中最好的。谢谢。 – zerkms