bash - 为什么 shell 会忽略通过变量传递给它的参数中的引号字符?

标签 bash variables syntax quoting expansion

<分区>

这些工作如广告所示:

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' 将是搜索路径。

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

谁能解释一下这是为什么?是否有适当的方法来扩展字符串变量,以保留每个字符的语法,以便 shell 命令正确解释它?

最佳答案

为什么

当字符串被扩展时,它被拆分成单词,但它不会重新评估以查找特殊字符,例如引号或美元符号或......这是外壳“总是”表现的方式,因为1978 年左右的 Bourne shell。

修复

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

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

或者,如果勇敢/有勇无谋,请使用 eval:

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

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

注意 Bash 的扩展顺序在 Shell Expansions 中描述。在 GNU Bash 手册中。请特别注意 3.5.3 Shell 参数扩展、3.5.7 单词拆分和 3.5.9 引用删除部分。

关于bash - 为什么 shell 会忽略通过变量传递给它的参数中的引号字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44617931/

相关文章:

bash - 为什么我的 expect 脚本在第 1 行失败?

python - 在python中将变量放在引号内

c++ - C++中的指针与变速

jquery - 您可以定义自己的 HTML 元素属性吗?

bash - 如何将文件逐行传输到多个读取变量中?

Bash:在同一行记录时间和命令输出

javascript - JS如何获取目标变量中的变量名?

javascript - 为 JavaScript 或其他语言实现自定义语法

javascript - 如何将此 CocoaScript “braces notation” 转换为 JavaScript “dot notation”(草图)?

json - 如何使用curl从bash变量发布整个json字符串?