Você deseja usar "$ @" (dólar entre aspas) para passar parâmetros para um subscrito. Igual a ....
ls-color.sh:
#!/bin/bash
/bin/ls --color=auto "$@" # passes though all CLI-args to 'ls'
Quanto ao porquê ...
Na página de manual do Bash :
$*
- Expande-se para os parâmetros posicionais, a partir de um. Quando a expansão ocorre entre aspas duplas, ela se expande para uma única palavra com o valor de cada parâmetro separado pelo primeiro caractere da variável especial IFS. Ou seja, "$*"
é equivalente a
"$1c$2c..."
, onde c é o primeiro caractere do valor da variável IFS. Se IFS não estiver definido, os parâmetros serão separados por espaços. Se IFS for nulo, os parâmetros serão unidos sem separadores intermediários.
$@
- Expande-se para os parâmetros posicionais, a partir de um. Quando a expansão ocorre entre aspas duplas, cada parâmetro se expande para uma palavra separada. Ou seja, "$@"
é equivalente a "$1" "$2" ...
Se a expansão entre aspas ocorrer dentro de uma palavra, a expansão do primeiro parâmetro é juntada com a parte inicial da palavra original, e a expansão do último parâmetro é juntada com a última parte do original palavra. Quando não há parâmetros posicionais
"$@"
e se $@
expandem para nada (ou seja, eles são removidos).
Configurando alguns scripts de demonstração ...
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 é uma transformação de identidade para repassar args para um subshell (~ 99% do tempo, isso é o que você pretendia fazer):
./quoted-dollar-at.sh aaa '' "'cc cc'" '"ddd ddd"'
# $1= aaa
# $2=
# $3= 'cc cc'
# $4= "ddd ddd"
"$*"
- a estrela de um dólar entre aspas esmaga os argumentos em uma única string (~ 1% do tempo em que você realmente deseja esse comportamento, por exemplo, em um condicional if [[ -z "$*" ]]; then ...
:):
./quoted-dollar-star.sh aaa '' "'cc cc'" '"ddd ddd"'
# $1= aaa 'cc cc' "ddd ddd"
# $2=
# $3=
# $4=
$*
/ $@
- sem aspas, ambas as formas retiram um nível de aspas e interpretam os espaços das strings subjacentes, mas ignoram os caracteres de aspas (quase sempre, isso é um erro):
./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
Se você quiser se divertir, pode usar "$ @" para aninhar as coisas tão profundamente quanto desejar, empurrando e removendo elementos da pilha de args se quiser.
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"