Estoy escribiendo un script muy simple que llama a otro script, y necesito propagar los parámetros de mi script actual al script que estoy ejecutando.
Por ejemplo, mi nombre de script es foo.sh
y llamabar.sh
foo.sh:
bar $1 $2 $3 $4
¿Cómo puedo hacer esto sin especificar explícitamente cada parámetro?
bash
command-line-arguments
Fragsworth
fuente
fuente
Respuestas:
Use en
"$@"
lugar de simple$@
si realmente desea que sus parámetros pasen lo mismo.Observar:
fuente
'arg with spaces'
para los tres ejemplos, también. Me sorprendieron los resultados; espero que puedas explicarlos../foo.sh "arg with spaces"
y./foo.sh 'arg with spaces'
son 100% idénticos, por lo que no veo cómo la sugerencia de agregarlo a los ejemplos dados sería de alguna ayuda.Para bash y otras conchas tipo Bourne:
fuente
$argv:q
vez funcione en algunas variantes de csh.exec java com.myserver.Program "$@"
Esto hace que bash se ejecute en java, en lugar de esperar a que se complete. Entonces, está utilizando una ranura de proceso menos. Además, si el proceso padre (que ejecutó su script) lo está viendo a través del pid, y espera que sea el proceso 'java', algunas cosas inusuales podrían romperse si no hace un ejecutivo; El ejecutivo hace que Java herede el mismo pid.args=("$@")
y expanda cada elemento como una "palabra" de shell separada ( similar a"$@"
) con"${args[@]}"
."$@"
, como fallará si ha escapado de espacios en una discusión, caracteres nulos u otros caracteres especiales?Uso
"$@"
(funciona para todos los POSIX compatibles).De Bash por ejemplo .
fuente
$*
. Creo que hay una progresión histórica aquí;$*
no funcionó como se diseñó, por lo que$@
se inventó para reemplazarlo; pero las reglas de comillas son lo que son, las comillas dobles a su alrededor todavía se requieren (o revertirá a la$*
semántica rota ).echo "$@"
como./script.sh a "b c" d
, solo obtiene ena b c d
lugar dea "b c" d
, que es muy diferente.echo
recibe tres argumentos:"a" "b c" "d"
(luego el shell los une como parte de su expansión de cadena). Pero si lo hubieras usado,for i in "$@"; do echo $i; done
lo hubieras conseguidoa⏎b c⏎d
.Me doy cuenta de que esto ha sido bien respondido, pero aquí hay una comparación entre "$ @" $ @ "$ *" y $ *
Contenido del guión de prueba:
Ahora, ejecute el script de prueba con varios argumentos:
fuente
Solo pensé que esto podría ser un poco más útil al intentar probar cómo los argumentos entran en tu script
fuente
$#
""
,''
como argumento, también si no hubo args, es silencioso. Intenté arreglar esto, pero necesito un bucle for y un contador con$#
. Acabo de agregar esto al final:echo "End of args or received quoted null"
Mi SUN Unix tiene muchas limitaciones, incluso "$ @" no se interpretó como se deseaba. Mi solución alternativa es $ {@}. Por ejemplo,
Por cierto, tenía que tener este script en particular porque mi Unix tampoco es compatible con grep -r
fuente
ksh
Si incluye
$@
una cadena entre comillas con otros caracteres, el comportamiento es muy extraño cuando hay varios argumentos, solo el primer argumento se incluye dentro de las comillas.Ejemplo:
Rendimientos:
Pero asignando a una variable diferente primero:
Rendimientos:
fuente
"$@"
in bash. También ayuda a ilustrar la diferencia clave entre$@
y$*
, y por qué ambos son útiles. Desde labash(1)
sección de parámetros especiales de la página de manual: "*
- Cuando la expansión se produce entre comillas dobles, se expande a una sola palabra con el valor de cada parámetro [...] Es decir,"$*"
es equivalente a"$1c$2c..."
, dondec
está [$IFS
]". Y, de hecho, usar en$*
lugar de$@
en su primer ejemplo habría generado una salida idéntica a la segunda versión."$@"
. De nuevo desde la página del manual: "@
- Cuando la expansión se produce entre comillas dobles, cada parámetro se expande a una palabra separada. Es decir,"$@"
es equivalente a"$1"
"$2"
... Si la expansión entre comillas dobles se produce 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 ". ... Y, de hecho, si tu código hubiera estadobash -c "true foo $@ bar baz"
, entonces ejecútalo como lotest.sh one two
haría netbash -c 'true foo one' 'two bar baz'
.$*
, parece olvidar que existe ...$@
estaba ganando terreno cuando comencé a usar scripts de shell, todavía tengo que recordarme a mí mismo que está allí. Era común ver que se"$*"
usaba en los scripts ... entonces el autor se daría cuenta de que estaba rompiendo todos sus argumentos juntos, por lo que probarían todo tipo de tonterías complejas con división de palabras"$*"
, o [re] ensamblar una lista arg por bucle másshift
que tirar de ellos uno por uno ... simplemente usando$@
lo resuelve. (Ayuda a que bash use la misma mnemónica para acceder a los miembros de la matriz, también:${var[*]}
para todos ellos como una palabra,${var[@]}
para una lista de palabras.)bash -c
de una manera que no tiene ningún sentido.A veces desea pasar todos sus argumentos, pero precedido por una bandera (por ejemplo
--flag
)Puede hacer esto de la siguiente manera:
nota: para evitar una división de campo adicional, debe citar
%s
y$@
, y para evitar tener una sola cadena, no puede citar la subshell deprintf
.fuente
Funciona bien, excepto si tiene espacios o caracteres escapados. No encuentro la forma de capturar argumentos en este caso y enviarlos a un ssh dentro del script.
Esto podría ser útil pero es tan feo
fuente
Muchas respuestas aquí recomiendan
$@
o$*
con o sin citas, sin embargo, ninguna parece explicar lo que realmente hacen y por qué debería hacerlo de esa manera. Así que déjame robar este excelente resumen de esta respuesta :Tenga en cuenta que las citas marcan la diferencia y sin ellas ambas tienen un comportamiento idéntico.
Para mi propósito, necesitaba pasar los parámetros de un script a otro tal cual y para eso la mejor opción es:
Observe que no hay comillas y
$@
debería funcionar tan bien en la situación anterior.fuente
bar "$@"
será equivalente abar "$1" "$2" "$3" "$4"
Tenga en cuenta que las comillas son importantes!
"$@"
,$@
,"$*"
O$*
se comportan cada uno un poco diferente con respecto a escapar y la concatenación como se describe en esta respuesta stackoverflow .Un caso de uso estrechamente relacionado es pasar todos los argumentos dados dentro de un argumento como este:
bash -c "bar \"$1\" \"$2\" \"$3\" \"$4\""
.Utilizo una variación de la respuesta de @ kvantour para lograr esto:
bash -c "bar $(printf -- '"%s" ' "$@")"
fuente