我已经重新设计了这个示例以保持简单,但我要做的是在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)在我的参数被破坏的点处显示单引号,这有点表明它正在考虑这些断点处的参数......只是不确定。
知道这里到底发生了什么吗?如何更改脚本?
提前致谢。
答案 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[@]}
那样被引用,那么它将被分成三个参数而不是两个参数。