本文介绍了将字符串转换为参数时,Bash 不解析引号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的问题.在 bash 3 中:

This is my problem. In bash 3:

$ test='One "This is two" Three'
$ set -- $test
$ echo $2
"This

如何让 bash 理解引号并将 $2 返回为 This is two 而不是 "This?不幸的是,我无法更改名为 的变量的构造在这个例子中测试.

How to get bash to understand the quotes and return $2 as This is two and not "This? Unfortunately I cannot alter the construction of the variable called test in this example.

推荐答案

发生这种情况的原因是 shell 解析命令行的顺序:它解析(并删除)引号和转义符,然后替换变量值.当 $testOne "This is two" Three 取代时,引号要达到预期效果为时已晚.

The reason this happens is because of the order in which the shell parses the command line: it parses (and removes) quotes and escapes, then replaces variable values. By the time $test gets replaced with One "This is two" Three, it's too late for the quotes to have their intended effect.

简单(但危险)的方法是使用 eval 添加另一个级别的解析:

The simple (but dangerous) way to do this is by adding another level of parsing with eval:

$ test='One "This is two" Three'
$ eval "set -- $test"
$ echo "$2"
This is two

(请注意,echo 命令中的引号不是必需的,但这是一个很好的通用做法.)

(Note that the quotes in the echo command are not necessary, but are a good general practice.)

我说这很危险的原因是它不仅返回并重新解析带引号的字符串,它还返回并重新解析所有内容,可能包括您不想像命令一样解释的内容替代品.假设你已经设置了

The reason I say this is dangerous is that it doesn't just go back and reparse for quoted strings, it goes back and reparses everything, maybe including things you didn't want interpreted like command substitutions. Suppose you had set

$ test='One `rm /some/important/file` Three'

...eval 实际上会运行 rm 命令.所以如果你不能指望 $test 的内容是安全的",不要使用这个结构.

...eval will actually run the rm command. So if you can't count on the contents of $test to be "safe", do not use this construct.

顺便说一句,做这种事情的正确方法是使用数组:

BTW, the right way to do this sort of thing is with an array:

$ test=(One "This is two" Three)
$ set -- "${test[@]}"
$ echo "$2"
This is two

不幸的是,这需要控制变量的创建方式.

Unfortunately, this requires control of how the variable is created.

这篇关于将字符串转换为参数时,Bash 不解析引号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-01 21:16