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
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:
if valnum "$num"
è equivalente aif valnum "$num" = 0
cioè ” se è vero “. regola pratica di base nello scripting sh è che 0 = vero / successo, diverso da zero = falso / errore.if [[ $(valNum $num) -eq 1 ]]