保护包含eval空格的参数

为了让eval能够处理其中一个参数中包含空格的命令,我只能发现这个function到目前为止:

eval 'sed 's/foo/foo'" "'bar/g' filename' 

在一个假设的程序中,用户可以input一个命令,然后命令和参数被input到eval中,这不是一个非常优雅或强大的解决scheme。 有没有其他方法来运行eval命令,以便my_command的界面可以更友好一些? 以下是程序如何接受参数的例子。

 my_command 'sed 's/foo/foo'" "'bar/g' filename' 

我希望界面能够像这样工作:

 my_command sed 's/foo/foo bar/g' filename 

编辑:

我会试着问一个不同的问题:

如何让bash从字面上从命令行读取input? 我想要保存确切的input,所以如果有引号,我想保留它们。 我可以通过使用egrep从文件读取然后消毒input来完成我想要做的事情,如下所示:

 egrep '/.*/' filename | sed 's/\(.*\)['"'"']\(.*\) \(.*\)['"'"']\(.*\)/\1'"\'"'\2" "\3'"\'"'\4/g' 

与“文件名”包含这一行

 sed 's/foo/foo bar/g' file 

这给了我所需的输出:

 sed 's/foo/foo" "bar/g' file 

这里的问题是我不能echo "$@"因为bash解释了引号。 我想要的文字input,而不必从文件读取。

原来的问题

对于你的首选用例,你只需写(在my_command ):

 "$@" 

按给定的方式执行命令。

你的eval线很奇怪:

 eval 'sed 's/foo/foo'" "'bar/g' filename' 

由于单引号不嵌套的方式,它相当于:

  eval 'sed s/foo/foo" "bar/g filename' 

修改后的问题

可能的方案

 egrep '/.*/' filename | sh 

这将filename直接提供给shell进行解释。 给定file包含:

 Some text containing foo; and bar. More foo bar? More text; more foo and bar; more foo bar beyond the possibility of unfooing. 

输出是:

 Some text containing foo bar; and bar. More foo bar bar? More text; more foo bar and bar; more foo bar bar beyond the possibility of unfoo baring. 

修复报价很难!

请注意,您的复杂sed脚本不够复杂。 给定filename包含:

 sed 's/foo/foo bar/g' file sed 's/foo bar/foo bar baz/g' file 

输出来自:

 egrep '/.*/' filename | sed 's/\(.*\)['"'"']\(.*\) \(.*\)['"'"']\(.*\)/\1'"\'"'\2" "\3'"\'"'\4/g' 

是:

 sed 's/foo/foo" "bar/g' file sed 's/foo bar/foo bar" "baz/g' file 

这并没有解决eval所有问题。

我花了很多时间,在相当长的一段时间内(从不夸张的话说,这个问题一直在这样的问题上工作),而且这不是微不足道的。 你可以在扩展中找到一个讨论如何迭代bash脚本中的参数 。 在某个地方,我还有另外一个关于这件事情的回答,但是我不能马上找到它(“立即”意味着一个小时左右的分心搜索,其中的分心是重复问题的集合等)。 它可能已被删除,或者我可能在错误的地方看过。

你的设计是有缺陷的。 创建一个不允许他们直接输入命令的用户界面。 给出选项,或让他们只输入参数。 在后端,在调用sed或其他所需工具之前,对参数进行消毒检查。 你不必使用eval

它实际上可以按照你的意愿工作。 使用"$@" – 这将完全按照在命令行上给出的方式传递所有参数。

如果my_command.sh包含:

 sed "$@" 

然后, my_command.sh 's/foo/foo bar/g' filename名将完全符合你的期望。