如何用引用的多字string作为参数?

我试图用一个stringvariables,包含多个带引号的单词作为参数给一个命令。

因此,给定以下示例脚本(注意shebang中的-x,这会导致输出logging到stderr)

#!/bin/bash -x myArg="\"hello\" \"world\"" echo "string is:" $myArg exit 

这给了我们,

 + myArg='"hello" "world"' + echo 'string is:' '"hello"' '"world"' string is: "hello" "world" + exit 

第二行显示实际传递给命令的内容; bash为string中的每个单词添加了单引号。 如果我改为引用“$ myArg”,那么对于整个string,而不是每个字都会发生同样的情况。

现在,设想一下,我们将string传递给一些需要引用模式的程序,比如"*" (它不能被shell扩展),而不是echo

为了澄清,我不想在扩展期间添加单引号。 我怎么能做到这一点?

不要使用引号,使用数组(请参阅BashFAQ#050 ):

 $ myArgs=("hello" "world" "multiword arg with * ?") + myArgs=("hello" "world" "multiword arg with * ?") $ echo "${myArgs[@]}" + echo hello world 'multiword arg with * ?' hello world multiword arg with * ? 

如果真的需要以字符串形式引用字符串,你要么必须使用eval "echo $myArg" (如果你不小心,会导致一些真正令人讨厌的错误)或解析它(这将是困难的)。

如果你想传递一个变量值作为参数(SO上的99%),只需使用适当的引用 :

 arg="foo bar" command "$arg" 

如果你想传递几个参数,使用数组:

 args=("foo bar" "baz ban" bay) command "${args[@]}" 

我不认为这是在做你认为正在做的事情。

 [~]$ myArg="\"hello\" \"world\"" [~]$ echo "string is:" $myArg string is: "hello" "world" 

我看不到任何额外的引号 – echo得到三个参数字符串。

 [~]$ cargs(){ echo $#; } [~]$ cargs "string is:" $myArg 3 

Bash将首先扩展变量,所以

 cargs "string is:" $myArg 

(虽然没有字面反斜杠 – 这就是为什么字符串逃脱是一个PITA)

 cargs "string is:" "\"hello\"" "\"world\"" 

args数组是:

 0x00:string is:0 0x0B:"hello"0 0x13:"world"0 0x1B:0 

现在,如果你在其中添加了*或glob路径扩展,那么Bash就会在这里扩展它,除非你转义它,或者在你的literal命令中使用单引号。

 [~]$ cargs "string is:" $myArg * 19 [~]$ cargs "string is:" $myArg "\*" 4 [~]$ cargs "string is:" $myArg '*' 4