我试图取代一个字符串变量,包含多个引用的话,作为一个参数的命令。
因此,给定以下示例脚本(注意在认领的-x,这导致输出要记录到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
第二行显示什么是真正传递给命令; 庆典增加了单引号字符串中的每一个字。 如果我不是,正是如此,引用“$ myArg”,同样会发生,但整个字符串,而不是每一个字。
现在,想象一下,而不是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"
我看到的任何kind-没有多余的报价echo
获得以上三个参数字符串。
[~]$ cargs(){ echo $#; }
[~]$ cargs "string is:" $myArg
3
bash将首先展开变量,所以
cargs "string is:" $myArg
变(虽然没有文字backslashes-这就是为什么字符串逃逸是一个PITA)
cargs "string is:" "\"hello\"" "\"world\""
而args数组是:
0x00:string is:0
0x0B:"hello"0
0x13:"world"0
0x1B:0
现在,如果您添加*
,或水珠路径扩展在其中的一个,bash将在这一点上展开它,除非你逃避它,或者在你的文字命令使用单引号。
[~]$ cargs "string is:" $myArg *
19
[~]$ cargs "string is:" $myArg "\*"
4
[~]$ cargs "string is:" $myArg '*'
4
有分裂展开变量,但保持空间的便携方式。 不需要猛砸阵列。 破折号(Ubuntu的/ bin / sh的)会的工作了。
使用某些字符分隔那是绝对不会的参数内使用的参数。 下面的示例使用分号,但它可能是一个新行或其它字符。 变化IFS
变量暂时换行符时的参数列表扩展。 恢复IFS
尽快为原始值,即使这意味着在循环做。 如果循环不能保证至少运行一次,做循环后也是如此。
#! /bin/sh
arg_list='hello world;have a nice day'
save_IFS="$IFS"
IFS=';'
for i in $arg_list; do
IFS="$save_IFS"
echo "$i"
done
IFS="$save_IFS"
需要注意的是每一个扩展的参数单独打印。
$ ./test.sh
hello world
have a nice day