2010-10-19 19 views

risposta

20

Di solito li si passa come parametri alla funzione al momento della chiamata.

L'alternativa (più brutta) è metterli in variabili globali.

3

Probabilmente dovresti usare "[email protected]" e passarlo alla fine dell'elenco degli argomenti della tua funzione. All'interno della funzione, shift dopo aver analizzato i tuoi argomenti e utilizzare $1 a $n come normalmente.

6

È possibile memorizzare tutti i tuoi argomenti di script in un array globale:

args=("[email protected]") 

e poi accedervi in ​​una funzione:

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

penso che 'funzione f() {' non è valido. Dovresti usare 'f() {' o 'function f {' invece. – Benoit

+0

Ho corretto la mia risposta, ma 'function f() {}' ha funzionato per me. – dogbane

16

(So che questo è un vecchio post, ma nessuno delle risposte ha effettivamente risposto alla domanda)

Utilizzare la matrice BASH_ARGV. Contiene gli argomenti passati allo script invocante in ordine inverso (vale a dire, è uno stack con la parte superiore all'indice 0). Potrebbe essere necessario attivare il debugging esteso nella shebang (ad esempio, #!/bin/bash -O extdebug) o con shopt (ad esempio, shopt -s extdebug), ma funziona per me in bash 4.2_p37 senza che sia attivato.

Da man bash:

Una variabile array contenente tutti i parametri nello stack bash esecuzione chiamata corrente. Il parametro finale dell'ultima chiamata di subroutine è in cima allo stack; il primo parametro della chiamata iniziale è in basso. Quando viene eseguita una subroutine, i parametri forniti vengono spinti su BASH_ARGV. La shell imposta BASH_ARGV solo in modalità debug estesa ....

Ecco una funzione che uso per stampare tutti gli argomenti in ordine su una sola riga:

# 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

buono a sapersi. sebbene il debugging esteso suoni un po 'paura. – zedoo

10

Come Benoit ha dichiarato, la soluzione più semplice è quello di passare gli argomenti della riga di comando alla funzione come argomenti di funzione con [email protected] , quindi è possibile fare riferimento a loro esattamente nello stesso modo al di fuori della funzione. In realtà, farai riferimento ai valori passati alla funzione che ha lo stesso valore degli argomenti della riga di comando, tieni questo in mente.

Si noti che questo quasi impedisce di passare qualsiasi altro argomento alla funzione, a meno che non si sappia esattamente quanti argomenti verranno passati alla riga di comando (improbabile che ciò dipenda dall'utente e non sia vincolato dal proprio vincoli)

ie

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

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

Un modo migliore è quello di passare solo gli argomenti che conoscete si prevede di utilizzare, in questo modo è possibile utilizzare con la funzione E anche passare altri parametri dall'interno del codice, se lo si desidera

cioè

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

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

È sufficiente passare il numero fisso di argomenti alla funzione all'inizio dell'elenco degli argomenti e, dopo averli elaborati nella funzione, utilizzare 'shift' per saltarli. ** Chiamata di funzione: ** 'fname farg1 farg2 farg3" $ @ "' ** Nella funzione dopo l'elaborazione dei tre argomenti: ** 'shift 3' – pabouk

+0

Questo è un buon punto. – CaffeineConnoisseur

+1

Puoi anche chiamare fname indicando quanti argomenti utente ci sono usando $ # permettendoti di specificare non solo argomenti extra prima, ma anche dopo così: 'fname beforearg $ #" $ @ "afterarg' –

0

Grazie per i suggerimenti: mi hanno ispirato a scrivere una funzione di callstack. Ho usato il comando 'column' per l'estetica.

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 
Problemi correlati