Accediendo a los argumentos de la línea de comando de bash $@ vs $*

Resuelto oz123 asked hace 12 años • 5 respuestas

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?

oz123 avatar Sep 07 '12 15:09 oz123
Aceptado

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
glenn jackman avatar Sep 07 '2012 10:09 glenn jackman

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 cen 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 .

Serge Stroobandt avatar Jan 22 '2015 22:01 Serge Stroobandt

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

Muffo avatar Sep 07 '2012 08:09 Muffo

$@ 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

rkosegi avatar Sep 07 '2012 08:09 rkosegi