Bash脚本接收和重新引用参数

我试图得到一个bash脚本的引用参数安全地被嵌套的脚本接收。 有任何想法吗?

test.sh

#!/bin/bash echo $* bash myecho.sh $* 

myecho.sh

 #!/bin/bash echo $1 echo $2 echo $3 echo $4 

样品:

 bash test.sh aaa bbb '"ccc ddd"' 

结果:

 aaa bbb "ccc ddd" aaa bbb "ccc ddd" 

想要的结果

 aaa bbb "ccc ddd" aaa bbb ccc ddd 
 #!/bin/bash echo $* bash myecho.sh "$@" 

请注意,“$ @”构造不是特定于bash的,并且应该与任何POSIX shell(至less使用破折号)一起工作。 还要注意,给定你想要的输出,你根本不需要额外的引用级别。 IE只需调用上面的脚本:

 ./test.sh 1 2 "3 4" 

你想使用“$ @”(引用美元在)将parameter passing给下标。 像这样….

ls-color.sh:

 #!/bin/bash /bin/ls --color=auto "$@" # passes though all CLI-args to 'ls' 

至于为什么…..

从Bash手册页 :

$* – 扩展到位置参数,从一开始。 当扩展出现在双引号内时,扩展为单个字,每个参数的值由IFS特殊variables的第一个字符分隔。 也就是说, "$*"相当于"$1c$2c..." ,其中c是IFSvariables值的第一个字符。 如果IFS未设置,则参数由空格分隔。 如果IFS为空,则参数在不插入分隔符的情况下进行连接。

$@ – 从一个开始扩展到位置参数。 当扩展出现在双引号内时,每个参数将扩展为一个单独的单词。 也就是说, "$@"相当于"$1" "$2" ...如果双引号扩展出现在一个单词内,则第一个参数的扩展与原始单词的开头部分相连,最后一个参数的最后一部分与原始单词连接。 当没有位置参数时, "$@"$@展开为空(即,它们被移除)。


设置一些演示脚本…

 echo 'echo -e "\$1=$1\n\$2=$2\n\$3=$3\n\$4=$4"' > echo-params.sh echo './echo-params.sh $*' > dollar-star.sh echo './echo-params.sh $@' > dollar-at.sh echo './echo-params.sh "$*"' > quoted-dollar-star.sh echo './echo-params.sh "$@"' > quoted-dollar-at.sh chmod +x *.sh 

"$@" – quoted-dollar-at是一个将args重新传递给子shell的身份转换 (大约99%的时间,这就是你的意思):

 ./quoted-dollar-at.sh aaa '' "'cc cc'" '"ddd ddd"' # $1= aaa # $2= # $3= 'cc cc' # $4= "ddd ddd" 

"$*" – quoted-dollar-star 将参数压缩成单个string (实际上需要这种行为的时间的1%,例如在条件if [[ -z "$*" ]]; then ...if [[ -z "$*" ]]; then ... ):

 ./quoted-dollar-star.sh aaa '' "'cc cc'" '"ddd ddd"' # $1= aaa 'cc cc' "ddd ddd" # $2= # $3= # $4= 

$* / $@ – 没有引号,两种forms剥离一个引用级别,并从底层string解释空格,但忽略引号字符(几乎总是,这是一个错误):

 ./dollar-star.sh aaa '' "'cc cc'" '"ddd ddd"' # $1= aaa # $2= 'cc # $3= cc' # $4= "ddd ./dollar-at.sh aaa '' "'cc cc'" '"ddd ddd"' # $1= aaa # $2= 'cc # $3= cc' # $4= "ddd 

如果你想获得一些乐趣,你可以使用“$ @”来嵌套事物,如果你愿意的话,可以将元素从堆栈中推出并popup。

 function identity() { "$@" } set -x identity identity identity identity identity echo Hello \"World\" # + identity identity identity identity identity echo Hello '"World"' # + identity identity identity identity echo Hello '"World"' # + identity identity identity echo Hello '"World"' # + identity identity echo Hello '"World"' # + identity echo Hello '"World"' # + echo Hello '"World"' # Hello "World"