为什么外壳程序会忽略通过变量传递给它的参数中的引号字符? [英] Why does shell ignore quoting characters in arguments passed to it through variables?

查看:56
本文介绍了为什么外壳程序会忽略通过变量传递给它的参数中的引号字符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这些作品如广告所示:

grep -ir 'hello world' .
grep -ir hello\ world .

这些不是:

argumentString1="-ir 'hello world'"
argumentString2="-ir hello\\ world"
grep $argumentString1 .
grep $argumentString2 .

在第二个示例中,尽管

'hello world'用引号引起来,但grep将'hello(和hello\)解释为一个参数,将world'(和world)解释为另一个参数,这意味着在这种情况下,'hello将是搜索模式,world'将是搜索路径.

Despite 'hello world' being enclosed by quotes in the second example, grep interprets 'hello (and hello\) as one argument and world' (and world) as another, which means that, in this case, 'hello will be the search pattern and world' will be the search path.

同样,仅当从argumentString变量扩展参数时,才会发生这种情况.在第一个示例中,grep正确地将'hello world'(和hello\ world)解释为单个参数.

Again, this only happens when the arguments are expanded from the argumentString variables. grep properly interprets 'hello world' (and hello\ world) as a single argument in the first example.

任何人都可以解释为什么会这样吗?是否有适当的方法来扩展一个字符串变量,该变量将保留每个字符的语法,以便由Shell命令正确解释?

Can anyone explain why this is? Is there a proper way to expand a string variable that will preserve the syntax of each character such that it is correctly interpreted by shell commands?

推荐答案

为什么

扩展字符串时,会将其拆分为单词,但是不会重新评估以查找特殊字符(例如引号或美元符号或...).这是外壳始终"运行的方式,因为伯恩(Bourne)炮弹可以追溯到1978年左右.

Why

When the string is expanded, it is split into words, but it is not re-evaluated to find special characters such as quotes or dollar signs or ... This is the way the shell has 'always' behaved, since the Bourne shell back in 1978 or thereabouts.

bash中,使用数组保存参数:

In bash, use an array to hold the arguments:

argumentArray=(-ir 'hello world')
grep "${argumentArray[@]}" .

或者,如果勇敢/很勇敢,请使用eval:

Or, if brave/foolhardy, use eval:

argumentString="-ir 'hello world'"
eval "grep $argumentString ."

另一方面,谨慎往往是勇气的重要部分,与eval一起工作是谨慎比勇敢更好的地方.如果您不能完全控制eval的字符串(如果命令字符串中有任何未经用户严格验证的用户输入),那么您将面临潜在的严重问题.

On the other hand, discretion is often the better part of valour, and working with eval is a place where discretion is better than bravery. If you are not completely in control of the string that is eval'd (if there's any user input in the command string that has not been rigorously validated), then you are opening yourself to potentially serious problems.

请注意, Shell中介绍了Bash的扩展顺序GNU Bash手册中的扩展.请特别注意3.5.3节Shell参数扩展,3.5.7分词和3.5.9引用删除.

Note that the sequence of expansions for Bash is described in Shell Expansions in the GNU Bash manual. Note in particular sections 3.5.3 Shell Parameter Expansion, 3.5.7 Word Splitting, and 3.5.9 Quote Removal.

这篇关于为什么外壳程序会忽略通过变量传递给它的参数中的引号字符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆