Restituzione di un valore da una funzione bash

Ho una funzione che restituisce 1 se il numero è un numero di dieci cifre valido:

valNum() { flag=1 if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then echo "Invalid Number" flag=0 fi return $flag } 

Viene chiamato da:

if [[ $(valNum $num) -eq 1 ]]; then #do something fi 

La funzione funziona bene se il numero è valido ma mostra la sintassi errore se si inserisce un numero non valido.

Risposta

La risposta di @choroba “è corretta, tuttavia questo esempio potrebbe essere più chiaro:

valNum $num valNumResult=$? # "$?" is the return value of the previous command if [[ $valNumResult -eq 1 ]] then : # do something fi 

Questo esempio è un po più lungo (impostando $valNumResult quindi interrogando quel valore), ma descrive in modo più esplicito cosa succede: che valNum() restituisce un valore e tale valore può essere interrogato e testato.

PS Fatevi un favore e restituite 0 per true e diverso da zero per false. In questo modo puoi utilizzare il valore restituito per indicare “perché abbiamo fallito” in caso di errore.

Answer

Le funzioni in bash possono restituire solo codici di uscita. La sostituzione del comando, al contrario, viene utilizzata per ottenere loutput standard di un comando o funzione. Pertanto, per controllare il flag restituito, non è necessaria la sostituzione:

if valNum "$num" ; then # ... fi 

Ma, affinché funzioni, è necessario restituire 0 se il numero è valido, e 1 se non lo è (il codice di uscita 0 significa nessun errore).

Commenti

  • Non capisco. Nellesempio 24.7 in tldp.org/LDP/abs/html/complexfunct.html la funzione restituisce il valore massimo e non il codice di uscita. Anche se il tuo suggerimento funziona ma non sono in grado di capire perché funziona
  • poiché il tuo test è scoprire se linput è un numero intero di 10 cifre valido o no, cioè vero o falso, la funzione restituisce 0 o 1. choroba ‘ s lesempio funziona perché if valnum "$num" è equivalente a if valnum "$num" = 0 cioè ” se è vero “. regola pratica di base nello scripting sh è che 0 = vero / successo, diverso da zero = falso / errore.
  • A proposito, quella ” Guida avanzata allo scripting di Bash ” non è ‘ una guida molto buona: ‘ è sbagliata su molte cose e incoraggia alcune cattive pratiche di scripting. la Bash FAQ su mywiki.wooledge.org/BashFAQ è una risorsa molto migliore.
  • vedi unix.stackexchange.com/questions/12236/ …
  • la tua funzione non funziona perché riproduce la stringa ” Numero non valido “, quindi fai un confronto numerico tra quella stringa e il numero 1 con if [[ $(valNum $num) -eq 1 ]]

Risposta

Non puoi restituire un risultato arbitrario da una funzione di shell. Puoi restituire solo un codice di stato che è un numero intero compreso tra 0 e 255. (sebbene tu possa passare un valore maggiore a return, viene troncato modulo 256.) Il valore deve essere 0 per indicare il successo e un valore diverso per indicare il fallimento; per convenzione dovresti attenersi a codici di errore compresi tra 1 e 125, poiché i valori più alti hanno un significato speciale (cattivo comando esterno per 126 e 127, ucciso da un segnale per valori più alti).

Dato che stai restituendo un risultato sì o no qui, un codice di stato è appropriato. Poiché flag sembra indicare un successo o un fallimento, dovresti usare i valori convenzionali 0 per successo e 1 per fallimento (lopposto di quello che hai scritto). È quindi possibile utilizzare la funzione direttamente in unistruzione if.

valNum () { local flag=0 if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then echo 1>&2 "Invalid Number" flag=1 fi return $flag } if valNum "$num"; then #do something fi 

Se è necessario discriminare tra i codici di errore, chiamare direttamente la funzione. Immediatamente dopo la restituzione, il codice di errore è disponibile in $?. Puoi quindi verificarlo con unistruzione case:

valNum "$num" case $? in … 

Se devi utilizzare il codice di stato in un secondo momento, salvalo in unaltra variabile prima di $? viene sovrascritto dal comando successivo.

valNum "$num" valNum_status=$? 

Ciò che hai scritto non” t ha funzionato perché la sostituzione del comando $(…) si espande nelloutput della funzione, che nel tuo codice è il messaggio di errore o è vuoto, mai 1.

Se hai bisogno per passare più informazioni di quelle consentite da un codice di stato da una funzione di shell, hai due possibilità:

  • Stampare del testo sullo standard output e chiamare la funzione in una sostituzione del comando: $(valNum "$num")
  • Assegna a una o più variabili allinterno della funzione e leggi quelle variabili in un secondo momento.

Risposta

Io stesso “ho avuto risultati contrastanti in questo settore. Ecco i risultati dei miei esperimenti empirici.In primo luogo, un po di “ teoria ” sui comandi bash o * nix:

  • SUCCESS == 0 … vale a dire. nessun codice di stato di errore)
  • FAIL              ! = 0 …… un po di codice di stato

Esempio:

if ls -lt /nonexistantdir then echo "found" else echo "FAIL" fi # echo ls -lt /nonexistantdir; echo "status = $?" echo "status = $?" 

Risultato:

ls: cannot access "/nonexistantdir": No such file or directory FAIL... ls: cannot access "/nonexistantdir": No such file or directory status = 2 

Come mostrato, il comando ls restituisce il codice di stato = 2. Quando provi una directory valida, lo stato è zero ( 0 ). Non è uguale a quasi tutte le altre lingue.

regola # 1 – Rendi …

  • VERO   == 0
  • FALSE! = 0

Dobbiamo ricordare che stiamo testando codici di errore in un if istruzione. Ho impostato le costanti oppure puoi utilizzare i comandi true o false della shell.

TRUE=0 FALSE=1 # valid number function # valNum() { flag=$TRUE if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then echo "Invalid Number" flag=$FALSE fi return $flag } # later on ... # if validNum Abc then echo "Lucky number" else echo "Not lucky." fi 

e output:

Invalid Number Not lucky. 

Tuttavia, ti suggerisco di dare qualsiasi “ up-vote “@Gilles perché la sua risposta è quella corretta. Volevo solo ottenere il lato semplicistico su ePaper.

Solo unaltra cosa, il test . Questo è simile a:

[[ some-expression ]]; 

La maggior parte delle volte. E ad esempio:

$ test 1 $ echo "result = $?" result = 0 $ test 0 $ echo "result = $?" result = 0 

Zero (0) è true . Perché? Bene, la pagina man dice che un singolo argomento è “ true ” quando è NOT-NULL.

riferimenti:

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *