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"