[email protected]и $* в bash script - программирование" />

Разница между [email protected]и $* в bash script

Ниже представлены 4 bash фрагмента. Я называю их ./script.sh a b c

for arg in [email protected]; do 
echo "$arg"
done   ## output "a\nb\nc"

for arg in "[email protected]"; do
echo "$arg"
done  ## output "a\nb\nc" -- I don't know why

for arg in $*; do
echo "$arg"
done  ##    output "a\nb\nc"

for arg in "$*"; do
echo "$arg"
done    ## output "abc"

Я не знаю, что такое точная разница между [email protected] и $*,
и я думаю, что "[email protected]" и "$*" должны быть одинаковыми, но это не так. Почему?

Ответ 1

Если у вас есть script foo.sh:

asterisk "$*"
at-sign "[email protected]"

и назовите его с помощью:

./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 [email protected]

будет эквивалентно:

asterisk "a" "a" "b" "b" "c" "c"
at-sign "a" "a" "b" "b" "c" "c"

Ответ 2

Разница между $* и [email protected]::

"$*" All the positional parameters (as a single word) *

"[email protected]" All the positional parameters (as separate strings)

Если вы передадите три аргумента командной строки, указанные в bash script, программе C, используя. /my _c [email protected],

вы получите результат ARG[1] == "par1" ARG[2] == "par2" ARG[3] == "par3"

Если вы передадите три аргумента командной строки, указанные в bash script, программе C, используя. /my _c $*,

вы получите результат ARG[1] == "par1 par2 par3"

Ответ 3

Это имеет значение в сценариях оболочки: например, script testargs.sh

#! /bin/bash -p

echo $#

for i in $(seq 1 $#)
do
    echo "$i: ${!i}"
done

for val in "[email protected]"; do
    echo "in quote @, $val"
done

for val in "$*"; do
    echo "in quote *, $val"
done

for val in [email protected]; do
    echo "not in quote @, $val"
done

for val in $*; do
    echo "not in quote *, $val"
done

Если этот script выполняется как /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 $#). Без кавычек оба одинаковы.