保护包含空格的参数免受 eval 影响

Jon*_*ler 4 unix linux bash shell eval

为了让 eval 能够处理参数之一内包含空格的命令,到目前为止我只发现它可以工作:

eval 'sed 's/foo/foo'" "'bar/g' filename'
Run Code Online (Sandbox Code Playgroud)

在一个假设的程序中,用户输入命令,然后将命令和参数输入到 eval,这不是一个非常优雅或强大的解决方案。是否有其他方法来运行 eval 命令,以便 my_command 的界面更加用户友好?以下是程序现在如何接受参数的示例。

my_command 'sed 's/foo/foo'" "'bar/g' filename'
Run Code Online (Sandbox Code Playgroud)

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

my_command sed 's/foo/foo bar/g' filename
Run Code Online (Sandbox Code Playgroud)

编辑:

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

如何让 bash 从命令行读取输入?我希望保留确切的输入,因此如果有引号我想保留它们。我可以通过使用egrep从文件中读取然后清理输入来完成我想做的事情,如下所示:

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

“文件名”包含这一行

sed 's/foo/foo bar/g' file
Run Code Online (Sandbox Code Playgroud)

这给了我所需的输出:

sed 's/foo/foo" "bar/g' file
Run Code Online (Sandbox Code Playgroud)

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

Jon*_*ler 6

原问题

对于您喜欢的用例,您只需编写(在 内部my_command):

"$@"
Run Code Online (Sandbox Code Playgroud)

执行给定的命令。

你的eval行很奇怪:

eval 'sed 's/foo/foo'" "'bar/g' filename'
Run Code Online (Sandbox Code Playgroud)

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

 eval 'sed s/foo/foo" "bar/g filename'
Run Code Online (Sandbox Code Playgroud)

修改后的问题

可能的解决方案:

egrep '/.*/' filename | sh
Run Code Online (Sandbox Code Playgroud)

这会将内容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.
Run Code Online (Sandbox Code Playgroud)

输出是:

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.
Run Code Online (Sandbox Code Playgroud)

修复报价很难!

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

sed 's/foo/foo bar/g' file
sed 's/foo bar/foo bar baz/g' file
Run Code Online (Sandbox Code Playgroud)

输出:

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

是:

sed 's/foo/foo" "bar/g' file
sed 's/foo bar/foo bar" "baz/g' file
Run Code Online (Sandbox Code Playgroud)

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

我断断续续地花了很多时间,在相当长的一段时间内(毫不夸张地说,四分之一个世纪)研究这些问题,而且这并不是微不足道的。您可以在如何迭代 bash 脚本中的参数中找到一个详细的讨论。在某个地方,我有另一个关于这个问题的答案,但我无法立即找到它(其中“立即”意味着一个小时左右的分心搜索,其中分心的是一组重复的问题等)。可能是被删了,或者是我看错地方了。