Bash和Double-Quotes传递给argv

时间:2013-12-06 16:47:52

标签: c bash arguments

我已经重新设计了这个示例以保持简单,但我要做的是在bash shell执行时将嵌套的双引号字符串作为单个argv值。

以下是脚本示例:

set -x
command1="key1=value1 \"key2=value2 key3=value3\""
command2="keyA=valueA keyB=valueB keyC=valueC"
echo $command1
echo $command2

输出是:

++ command1='key1=value1 "key2=value2 key3=value3"'
++ command2='keyA=valueA keyB=valueB keyC=valueC'
++ echo key1=value1 '"key2=value2' 'key3=value3"'
key1=value1 "key2=value2 key3=value3"
++ echo keyA=valueA keyB=valueB keyC=valueC
keyA=valueA keyB=valueB keyC=valueC

我也测试过,当你在命令行上执行所有操作时,嵌套的引用消息IS被设置为单个argv值。即。

prog.exe argument1 "argument2 argument3"

argv[0] = prog.exe
argv[1] = argument1
argv[2] = argument2 argument3

使用上面的例子:

command1="key1=value1 \"key2=value2 key3=value3\""

错误是,我的argv正在回复:

arg[1] = echo 
arg[2] = key1=value1 
arg[3] = "key2=value2
arg[4] = key3=value3"

我真的希望我的argv [3]值为“key2 = value2 key3 = value3”

我注意到debug(set -x)在我的参数被破坏的点处显示单引号,这有点表明它正在考虑这些断点处的参数......只是不确定。

知道这里到底发生了什么吗?如何更改脚本?

提前致谢。

2 个答案:

答案 0 :(得分:4)

发生的事情是你的嵌套引号是文字的,而不是由shell解析成单独的参数。使用bash处理此问题的最佳方法是使用数组而不是字符串:

args=('key1=value1', 'key2=value2 key3=value3')
prog.exe "${args[@]}"

Bash FAQ50还有一些动态命令的示例和用例。

答案 1 :(得分:1)

一种疯狂的“回答”是将IFS设置为双引号(保存/恢复原始IFS):

SAVED_IFS=$IFS
IFS=$'\"'
prog.exe $command1

IFS=$SAVED_IFS

它说明了在不带引号的参数上发生的单词拆分,但不影响".."引号内的变量或文本。双引号内的文本(在各种扩展之后)作为单个参数传递给程序。然而,一个裸变量$ command1(未引用的)经历了单词拆分,它不关心变量内部的"(以字面为单位)。一个愚蠢的IFS黑客强迫在"进行分词。还要注意argv [1]末尾的尾随空格,因为"边界处的单词分裂而出现。

jordanm对生产使用的回答比我的好得多:)引用了数组,即每个数组元素都作为单独的字符串扩展,之后不会发生分词。这很重要。如果它不像${args[@]}那样被引用,那么它将被分成三个参数而不是两个参数。