Accediendo a los argumentos de la línea de comando de bash $@ vs $*
En muchas preguntas SO y tutoriales de bash, veo que puedo acceder a los argumentos de la línea de comando en scripts de bash de dos maneras:
$ ~ >cat testargs.sh
#!/bin/bash
echo "you passed me" $*
echo "you passed me" $@
Lo que resulta en:
$ ~> bash testargs.sh arg1 arg2
you passed me arg1 arg2
you passed me arg1 arg2
¿ Cuál es la diferencia entre $*
y $@
?
¿Cuándo se debe utilizar el primero y cuándo se debe utilizar el segundo?
La diferencia aparece cuando se citan los parámetros especiales. Permítanme ilustrar las diferencias:
$ set -- "arg 1" "arg 2" "arg 3"
$ for word in $*; do echo "$word"; done
arg
1
arg
2
arg
3
$ for word in $@; do echo "$word"; done
arg
1
arg
2
arg
3
$ for word in "$*"; do echo "$word"; done
arg 1 arg 2 arg 3
$ for word in "$@"; do echo "$word"; done
arg 1
arg 2
arg 3
Un ejemplo más sobre la importancia de citar: tenga en cuenta que hay 2 espacios entre "arg" y el número, pero si no cito $word:
$ for word in "$@"; do echo $word; done
arg 1
arg 2
arg 3
y en bash, "$@"
está la lista "predeterminada" sobre la que iterar:
$ for word; do echo "$word"; done
arg 1
arg 2
arg 3
Una tabla de descripción general útil y útil de Bash Hackers Wiki :
Sintaxis | Resultado efectivo |
---|---|
$* |
$1 $2 $3 … ${N} |
$@ |
$1 $2 $3 … ${N} |
"$*" |
"$1c$2c$3c…c${N}" |
"$@" |
"$1" "$2" "$3" … "${N}" |
donde c
en la tercera fila está el primer carácter de $IFS
, el separador de campo de entrada , una variable de shell.
Si los argumentos se van a almacenar, cárguelos en una variable de matriz .
ps
Se expande a los parámetros posicionales, comenzando desde uno. Cuando la expansión ocurre entre comillas dobles, se expande a una sola palabra con el valor de cada parámetro separado por el primer carácter de la variable especial IFS. Es decir, "$*" equivale a "$1c$2c...", donde c es el primer carácter del valor de la variable IFS. Si IFS no está configurado, los parámetros están separados por espacios. Si IFS es nulo, los parámetros se unen sin que intervengan separadores.
ps
Se expande a los parámetros posicionales, comenzando desde uno. Cuando la expansión se produce entre comillas dobles, cada parámetro se expande a una palabra separada. Es decir, "$@" equivale a "$1" "$2"... Si la expansión entre comillas dobles ocurre dentro de una palabra, la expansión del primer parámetro se une con la parte inicial de la palabra original, y la expansión del último parámetro se une con la última parte de la palabra original. Cuando no hay parámetros posicionales, "$@" y $@ se expanden hasta quedar en nada (es decir, se eliminan).
Fuente: hombre bash
$@ es lo mismo que $*, pero cada parámetro es una cadena entre comillas, es decir, los parámetros se pasan intactos, sin interpretación ni expansión. Esto significa, entre otras cosas, que cada parámetro de la lista de argumentos se considera una palabra independiente.
Por supuesto, se debe citar "$@".
http://tldp.org/LDP/abs/html/internalvariables.html#ARGLIST