为了让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
名将完全符合你的期望。