下面有 4 个 bash 片段。我用./script.sh a b c
称呼他们
for arg in $@; do
echo "$arg"
done ## output "anbnc"
for arg in "$@"; do
echo "$arg"
done ## output "anbnc" -- I don't know why
for arg in $*; do
echo "$arg"
done ## output "anbnc"
for arg in "$*"; do
echo "$arg"
done ## output "abc"
我不知道$@
和$*
之间的确切区别是什么,
我认为"$@"
和"$*"
应该是一样的,但事实并非如此。为什么?
如果你有一个脚本foo.sh
:
asterisk "$*"
at-sign "$@"
并调用它:
./foo.sh "a a" "b b" "c c"
它相当于:
asterisk "a a b b c c"
at-sign "a a" "b b" "c c"
没有引号,它们是相同的:
asterisk $*
at-sign $@
等效于:
asterisk "a" "a" "b" "b" "c" "c"
at-sign "a" "a" "b" "b" "c" "c"
$* 和 $@ 之间的区别是:
"$*" All the positional parameters (as a single word) *
"$@" All the positional parameters (as separate strings)
如果使用 ./my_c $@ 将提供给 bash 脚本的三个命令行参数传递给 C 程序,
你得到的结果ARG[1] == "par1" ARG[2] == "par2" ARG[3] == "par3"
如果使用 .//my_c $* 将提供给 bash 脚本的三个命令行参数传递给 C 程序,
你得到的结果ARG[1] == "par1 par2 par3"
在 shell 脚本中很重要:例如脚本 testargs.sh
#! /bin/bash -p
echo $#
for i in $(seq 1 $#)
do
echo "$i: ${!i}"
done
for val in "$@"; do
echo "in quote @, $val"
done
for val in "$*"; do
echo "in quote *, $val"
done
for val in $@; do
echo "not in quote @, $val"
done
for val in $*; do
echo "not in quote *, $val"
done
如果此脚本按/tmp/testargs.sh a b c 'd e'
执行,结果是:
4
1: a
2: b
3: c
4: d e
in quote @, a
in quote @, b
in quote @, c
in quote @, d e
in quote *, a b c d e
not in quote @, a
not in quote @, b
not in quote @, c
not in quote @, d
not in quote @, e
not in quote *, a
not in quote *, b
not in quote *, c
not in quote *, d
not in quote *, e
因此,如果要保留参数的数量,请始终使用"$@"或使用for i in $(seq 1 $#)
循环遍历每个参数。没有引号,两者都是一样的。