receive - Accediendo a la línea de comandos de bash args $ @ vs $*
sh script parameter (4)
En muchas preguntas de SO y tutoriales de bash veo que puedo acceder a los argumentos de la línea de comandos en los 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 usar el primero y cuándo se debe usar el segundo?
$ @ es igual que $ *, pero cada parámetro es una cadena entrecomillada, es decir, los parámetros se pasan intactos, sin interpretación ni expansión. Esto significa, entre otras cosas, que cada parámetro en la lista de argumentos se ve como una palabra separada.
Por supuesto, "$ @" debe ser citado.
La diferencia aparece cuando se citan los parámetros especiales. Déjame 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 las citas: note que hay 2 espacios entre "arg" y el número, pero si no cito $ palabra:
$ for word in "$@"; do echo $word; done
arg 1
arg 2
arg 3
y en bash, "$@"
es la lista "predeterminada" para iterar sobre:
$ for word; do echo "$word"; done
arg 1
arg 2
arg 3
Una bonita y práctica tabla de resumen de la Wiki de Bash Hackers :
donde c
en la tercera fila es el primer carácter de $IFS
, el Separador de campo interno; una variable de entorno.
Si los argumentos se almacenan en una variable de secuencia de comandos y se espera que los argumentos contengan espacios, recomiendo de todo corazón emplear un truco "$*"
con el separador de campo interno $IFS
configurado para tabular .
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, "$ *" es equivalente 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 ocurre dentro de comillas dobles, cada parámetro se expande a una palabra separada. Es decir, "$ @" es equivalente a "$ 1" "$ 2" ... Si la expansión de doble comillas 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 a nada (es decir, se eliminan).
Fuente: Bash man