2010-10-19 18 views

Respuesta

20

Normalmente solo los pasa como parámetros a la función en el tiempo de llamada.

La alternativa (más fea) es ponerlos en variables globales.

3

Probablemente deberías usar "[email protected]" y pasar eso al final de la lista de argumentos de tu función. Dentro de la función, shift después de analizar sus argumentos y use $1 como $n como normalmente.

6

Puede almacenar todos sus argumentos del script en una matriz global:

args=("[email protected]") 

y luego acceder a ellos de una función:

f(){ 
    echo ${args[0]} ${args[1]} 
} 
+1

creo que 'función f() {' no es válido. Deberías usar 'f() {' o 'función f {' en su lugar. – Benoit

+0

He corregido mi respuesta, pero 'function f() {}' me funcionó. – dogbane

16

(Sé que esto es una entrada antigua, pero ninguno de las respuestas realmente respondieron la pregunta.)

Utilice la matriz BASH_ARGV. Contiene los argumentos pasados ​​al script de invocación en orden inverso (es decir, es una pila con la parte superior en el índice 0). Es posible que deba activar la depuración extendida en el shebang (por ejemplo, #!/bin/bash -O extdebug) o con shopt (por ejemplo, shopt -s extdebug), pero funciona para mí en bash 4.2_p37 sin que esté activado.

De man bash:

una variable de matriz que contiene todos los parámetros en la pila fiesta llamada de ejecución actual. El parámetro final de la última llamada de subrutina está en la parte superior de la pila; el primer parámetro de la llamada inicial está en la parte inferior. Cuando se ejecuta una subrutina, los parámetros suministrados se insertan en BASH_ARGV. El shell establece BASH_ARGV solo cuando está en modo de depuración extendida ....

Aquí es una función que utilizo para imprimir todos los argumentos en orden en una sola línea:

# Print the arguments of the calling script, in order. 
function get_script_args 
{ 
    # Get the number of arguments passed to this script. 
    # (The BASH_ARGV array does not include $0.) 
    local n=${#BASH_ARGV[@]} 

    if (($n > 0)) 
    then 
     # Get the last index of the args in BASH_ARGV. 
     local n_index=$(($n - 1)) 

     # Loop through the indexes from largest to smallest. 
     for i in $(seq ${n_index} -1 0) 
     do 
      # Print a space if necessary. 
      if (($i < $n_index)) 
      then 
       echo -n ' ' 
      fi 

      # Print the actual argument. 
      echo -n "${BASH_ARGV[$i]}" 
     done 

     # Print a newline. 
     echo 
    fi 
} 
+0

es bueno saberlo. aunque la depuración extendida suena un poco aterradora. – zedoo

10

Como Benoit ha indicado, la solución más sencilla es pasar los argumentos de línea de comandos a la función como argumentos de la función con [email protected] , entonces puede hacer referencia a ellos exactamente de la misma manera que fuera de la función. En realidad, hará referencia a los valores pasados ​​a la función que tiene el mismo valor que los argumentos de la línea de comando, téngalo en cuenta.

Tenga en cuenta que esto prácticamente le impide pasar cualquier otro argumento a la función, a menos que sepa exactamente cuántos argumentos se pasarán en la línea de comandos (poco probable ya que depende del usuario y no está sujeto a su restricciones)

ie

function fname { 
    # do something with $1 $2 $3...$n # 
    } 

    # [email protected] represents all the arguments passed at the command line # 
    fname [email protected] 

Una mejor manera es pasar sólo los argumentos que usted sabe que va a utilizar, de esa manera se puede utilizar en la función y también pasar otros parámetros desde el código si lo desea

es decir

function fname { 
    # do something with $1 $count $2 and $3 # 
    } 

    count=1 
    fname $1 $count $2 $3 
+2

Simplemente puede pasar un número fijo de argumentos a la función al principio de la lista de argumentos y luego, después de procesarlos en la función, use 'shift' para omitirlos. ** Llamada de función: ** 'fname farg1 farg2 farg3" $ @ "' ** En la función después de procesar los tres argumentos: ** 'shift 3' – pabouk

+0

Ese es un buen punto. – CaffeineConnoisseur

+1

También podría llamar a fname diciéndole cuántos argumentos de usuario hay usando $ # lo que le permite no solo especificar argumentos adicionales antes, sino también después de eso: 'fname beforearg $ #" $ @ "afterarg' –

0

Gracias por los consejos: me inspiraron a escribir una función de pila de llamadas. Usé el comando 'columna' para estética.

callstack() { 
    local j=0 k prog=$(basename $0) 
    for ((i=1; ((i<${#BASH_ARGC[*]})); i++)) 
    do 
     echo -n "${FUNCNAME[$i]/main/$prog} " # function name 
     args="" 
     for ((k=0; ((k<${BASH_ARGC[$i]})); k++)) 
     do 
      args="${BASH_ARGV[$j]} $args" # arguments 
      let j++ 
     done 
     echo -e "$args\t|${BASH_LINENO[$i]}" $(sed -n ${BASH_LINENO[$i]}p "$0" 2>/dev/null) # line calling the function 
    done | column -t -s $'\t' -o ' ' | sed 1d # delete callstack entry 
} 
 
compareTemplates brother_001270_1.jpg  |163 compareTemplates "$f" # process the rest 
processPdf brother_001270.pdf    |233 filetype "${f%[*}" pdf && processPdf "$f" 
process brother_001270.pdf    |371 --process) shift; process "[email protected]"; exit ;; # process jpg or pdf 
sm --quiet --process brother_001270.pdf |0 
Cuestiones relacionadas