2010-04-29 11 views
59

Estoy intentando escribir una función en bash que acceda a los argumentos de línea de comandos de scripts, pero se reemplazan con los argumentos posicionales de la función. ¿Hay alguna manera para que la función acceda a los argumentos de la línea de comandos si no se pasan explícitamente?En Bash, ¿cómo se accede a los argumentos de línea de comando dentro de una función?

# Demo function 
function stuff { 
    echo $0 $* 
} 

# Echo's the name of the script, but no command line arguments 
stuff 

# Echo's everything I want, but trying to avoid 
stuff $* 
+3

estoy algo confundido, desea que el args sin ellos pasando ? –

+2

Sí, el punto es obtener también los argumentos de la línea de comando desde el interior de una función sin pasarlos como argumentos funcionales. Tiene que ver con una situación de manejo de errores en la que quiero hacer un manejo de errores basado en argumentos de línea de comando independientemente de los argumentos pasados ​​a la función. – DonGar

Respuesta

30

Mi lectura del manual bash ref dice que esto se captura en BASH_ARGV, aunque habla mucho de "la pila".

#!/bin/bash 

function argv { 
    for a in ${BASH_ARGV[*]} ; do 
     echo -n "$a " 
    done 
    echo 
} 

function f { 
    echo f $1 $2 $3 
    echo -n f ; argv 
} 

function g { 
    echo g $1 $2 $3 
    echo -n g; argv 
    f 
} 

f boo bar baz 
g goo gar gaz 

Guardar en f.sh

$ ./f.sh arg0 arg1 arg2 
f boo bar baz 
farg2 arg1 arg0 
g goo gar gaz 
garg2 arg1 arg0 
f 
farg2 arg1 arg0 
+4

Ten en cuenta que iterar la matriz de esa manera hace que los argumentos estén en orden inverso desde la línea de comandos. –

8
#!/usr/bin/env bash 

echo name of script is $0 
echo first argument is $1 
echo second argument is $2 
echo seventeenth argument is $17 
echo number of arguments is $# 

Editar: por favor ver mi comentario sobre la pregunta

64

Si usted quiere tener su estilo C argumentos (array de parámetros + número de argumentos) que puede utilizar $ @ y $ #.

$ # le da la cantidad de argumentos. $ @ le da todos los argumentos. se puede convertir esto en una matriz por args=("[email protected]")

Así, por ejemplo:

args=("[email protected]") 
echo $# arguments passed 
echo ${args[0]} ${args[1]} ${args[2]} 

Nota thate aquí ${args[0]} realidad es la primera argumento y no el nombre de su script.

+1

Esto no responde a la pregunta: pregunta por pasar los argumentos de la línea de comandos a una función de shell. – Cascabel

+5

@Jefromi, en realidad, responde la pregunta perfectamente. Puede usar la matriz 'args' desde dentro de una función, si la inicializa de antemano como se describe. – vadipp

+1

Encuentro esto mucho más limpio que iterar sobre los argumentos. –

5
# Save the script arguments 
SCRIPT_NAME=$0 
ARG_1=$1 
ARGS_ALL=$* 

function stuff { 
    # use script args via the variables you saved 
    # or the function args via $ 
    echo $0 $* 
} 


# Call the function with arguments 
stuff 1 2 3 4 
14

El comentario de Ravi es esencialmente la respuesta. Las funciones toman sus propios argumentos. Si desea que sean los mismos que los argumentos de la línea de comandos, debe pasarlos. De lo contrario, está llamando claramente a una función sin argumentos.

Dicho esto, se podía si desea almacenar los argumentos de línea de comandos en una matriz global para usar dentro de otras funciones:

my_function() { 
    echo "stored arguments:" 
    for arg in "${commandline_args[@]}"; do 
     echo " $arg" 
    done 
} 

commandline_args=("[email protected]") 

my_function 

Usted tiene que acceder a los argumentos de línea de comandos a través de la variable commandline_args, no [email protected], $1, $2, etc., pero están disponibles. No conozco ninguna forma de asignar directamente el argumento matriz, pero si alguien conoce uno, ¡por favor ilumíname!

Además, tenga en cuenta la forma en que he utilizado y citado [email protected] - así es como se aseguran de que los caracteres especiales (espacios en blanco) no se arruinen.

2

Usted puede utilizar la palabra clave de cambio (operador?) Para iterar a través de ellos. Ejemplo:

#!/bin/bash 
function print() 
{ 
    while [ $# -gt 0 ] 
    do 
     echo $1; 
     shift 1; 
    done 
} 
print $*; 
2

Uno puede hacerlo de esta manera, así

#!/bin/bash 
# script_name function_test.sh 
function argument(){ 
for i in [email protected];do 
    echo $i 
done; 
} 
argument [email protected] 

Ahora llame a su guión como

./function_test.sh argument1 argument2 
Cuestiones relacionadas