Qual è la differenza tra l' istruzione return
e exit
nelle funzioni di Bash rispetto ai codici di uscita?
Qual è la differenza tra l' istruzione return
e exit
nelle funzioni di Bash rispetto ai codici di uscita?
Risposte:
Da man bash
su return [n]
;
Fa interrompere l'esecuzione di una funzione e restituisce il valore specificato da n al suo chiamante. Se n viene omesso, lo stato di ritorno è quello dell'ultimo comando eseguito nel corpo della funzione.
... su exit [n]
:
Fa uscire la shell con uno stato di n. Se n viene omesso, lo stato di uscita è quello dell'ultimo comando eseguito. Una trap su EXIT viene eseguita prima che la shell termini.
MODIFICARE:
Secondo la modifica della domanda, per quanto riguarda i codici di uscita, return
non ha nulla a che fare con i codici di uscita. I codici di uscita sono destinati ad applicazioni / script , non a funzioni. Quindi, a questo proposito, l'unica parola chiave che imposta il codice di uscita dello script (quella che può essere catturata dal programma chiamante usando la $?
variabile shell) è exit
.
MODIFICA 2:
La mia ultima dichiarazione di riferimento exit
sta causando alcuni commenti. È stato fatto per differenziare return
e exit
per la comprensione dell'OP, e in effetti, in un dato punto di uno script programma / shell, exit
è l'unico modo per terminare lo script con un codice di uscita al processo chiamante.
Ogni comando eseguito nella shell produce un "codice di uscita" locale: imposta la $?
variabile di quel codice, e può essere utilizzato con if
, &&
e altri operatori ai condizionale eseguire altri comandi.
Questi codici di uscita (e il valore della $?
variabile) vengono ripristinati da ogni esecuzione del comando.
Per inciso, il codice di uscita dell'ultimo comando eseguito dallo script viene utilizzato come codice di uscita dello script stesso come visto dal processo di chiamata.
Infine, le funzioni, quando chiamate, agiscono come comandi di shell rispetto ai codici di uscita. Il codice di uscita della funzione ( all'interno della funzione) viene impostato utilizzando return
. Pertanto, quando return 0
viene eseguita una funzione , l'esecuzione della funzione termina, fornendo un codice di uscita pari a 0.
func(){ return 50; };func;echo $?
riecheggia 50. Quindi la $?
variabile shell non sembra essere limitata a exit
.
$?
espande allo stato di uscita della pipeline in primo piano eseguita più di recente." Tale uscita può provenire dalla shell sotto forma di una chiamata exit
(o colpire la fine dello script) o sotto forma di una chiamata return
all'interno di una funzione.
$?
il processo / script corrente è limitato exit
o al risultato dell'ultimo comando eseguito da questo script. Quindi, se la tua ultima riga di script è la chiamata a quella funzione e quella funzione restituisce 50, sì, $?
quello che produci nel processo che ti ha chiamato è 50. Tuttavia, ciò non ha a che fare con il return
, perché questo è limitato allo script corrente. Succede di essere restituito solo se questa chiamata di funzione è l'ultima frase dello script. exit
tuttavia, completare sempre lo script e restituire quel valore per quanto $?
riguarda il processo di chiamata .
return
non ha nulla a che fare con i codici di uscita". La sperimentazione mi dice che non esiste alcuna differenza funzionale tra il codice di ritorno di una funzione e il codice di uscita di uno script.
return
farà sì che la funzione corrente esca dall'ambito, mentre exit
farà terminare lo script nel punto in cui viene chiamato. Ecco un programma di esempio per spiegare questo:
#!/bin/bash
retfunc()
{
echo "this is retfunc()"
return 1
}
exitfunc()
{
echo "this is exitfunc()"
exit 1
}
retfunc
echo "We are still here"
exitfunc
echo "We will never see this"
$ ./test.sh
this is retfunc()
We are still here
this is exitfunc()
$?
.
echo fnord | while read x; do exitfunc; done; echo "still here"
verrà stampato "ancora qui". Sembra che solo la while
sotto-shell sia uscita in questo scenario.
done || exit $?
che è brutta e non esattamente equivalente.
return
farà sì che la funzione corrente o lo script di provenienza vadano fuori dall'ambito ''.
Non credo che nessuno abbia veramente risposto completamente alla domanda perché non descrivono come vengono usati i due. OK, penso che sappiamo che exit uccide lo script, dovunque venga chiamato e puoi assegnargli uno stato come exit o exit 0 o exit 7 e così via. Questo può essere usato per determinare come lo script è stato costretto a fermarsi se chiamato da un altro script ecc. Basta all'uscita.
return quando chiamato restituirà il valore specificato per indicare il comportamento della funzione, generalmente un 1 o uno 0. Ad esempio:
#!/bin/bash
isdirectory() {
if [ -d "$1" ]
then
return 0
else
return 1
fi
echo "you will not see anything after the return like this text"
}
controlla in questo modo:
if isdirectory $1; then echo "is directory"; else echo "not a directory"; fi
o in questo modo:
isdirectory || echo "not a directory"
In questo esempio, il test può essere utilizzato per indicare se la directory è stata trovata. notare che qualsiasi cosa dopo il ritorno non verrà eseguita nella funzione. 0 è vero ma falso è 1 nella shell, diverso dagli altri linguaggi prog.
Per maggiori informazioni sulle funzioni: http://www.linuxjournal.com/content/return-values-bash-functions
NOTA: la funzione isdirectory è solo a scopo didattico. Questo non dovrebbe essere il modo in cui esegui tale opzione in uno script reale.
test -d $1
per ottenere lo stesso risultato. Non farlo mai if <check> return else return
. <check>
da solo farà la stessa cosa in tutte le lingue che conosco almeno.
isdirectory() { [ -d "$1" ]; }
si comporterà esattamente come quello che hai qui: il valore di ritorno predefinito di una funzione shell, sia raggiungendo la fine del suo codice sia con un return
senza argomenti, è quello del comando più recente.
return
dell'affermazione. È vero che il suo esempio è semplicistico e non può essere usato in produzione. Ma è semplice, quindi svolge perfettamente il suo compito. Niente di sbagliato.
Ricorda, le funzioni sono interne a uno script e normalmente ritornano da dove sono state chiamate usando l'istruzione return. La chiamata di uno script esterno è completamente un'altra questione e gli script di solito terminano con un'istruzione exit.
La differenza "tra l'istruzione return e exit nelle funzioni BASH rispetto ai codici di uscita" è molto piccola. Entrambi restituiscono uno stato, non valori di per sé. Uno stato zero indica il successo, mentre qualsiasi altro stato (da 1 a 255) indica un errore. L'istruzione return tornerà allo script da dove è stata chiamata, mentre l'istruzione exit finirà l'intero script da dove viene incontrata.
return 0 # returns to where the function was called. $? contains 0 (success).
return 1 # returns to where the function was called. $? contains 1 (failure).
exit 0 # exits the script completely. $? contains 0 (success).
exit 1 # exits the script completely. $? contains 1 (failure).
Se la tua funzione termina semplicemente senza alcuna dichiarazione di ritorno, lo stato dell'ultimo comando eseguito viene restituito come codice di stato (e verrà inserito $?
).
Ricorda, return e exit restituiscono un codice di stato da 0 a 255, disponibile in $?
. Non è possibile inserire altro in un codice di stato (ad es. Return "cat"); non funzionerà. Tuttavia, uno script può restituire 255 diversi motivi di errore utilizzando i codici di stato.
È possibile impostare le variabili contenute nello script chiamante o ottenere risultati echo nella funzione e utilizzare la sostituzione dei comandi nello script chiamante; ma lo scopo di return e exit è passare codici di stato, non valori o risultati di calcolo come ci si potrebbe aspettare in un linguaggio di programmazione come C.
A volte, esegui uno script usando .
o source
.
. a.sh
Se si include un exit
in a.sh
, non solo terminerà lo script, ma terminerà la sessione della shell.
Se includi a return
in a.sh
, semplicemente interrompe l'elaborazione dello script.
return: can only 'return' from a function or sourced script
, il che lo rende inadatto per uno script generale.
all
situazioni. Usare .
o source
eseguire lo script nella shell corrente, anziché generare una sotto-shell. Lo script deve sapere come deve essere utilizzato. Guai all'utente che lo fa di fronte. Personalmente, consiglio di leggere gli script prima di eseguirli la prima volta.
trap
funzione per ERR EXIT
e quindi prima salvare il codice di uscita di un comando non riuscito errCode=$?
e quindi uscire dallo script (di provenienza o meno) con return $errCode || exit $errCode
dove ||
significa "se non posso tornare perché non ero di provenienza , basta uscire invece ".
In parole semplici (principalmente per i principianti nella codifica), possiamo dire,
`return` : exits the function,
`exit()` : exits the program(called as process while running)
Anche se hai osservato, questo è molto semplice ma ...,
`return` : is the keyword
`exit()` : is the function
exit
non è più o meno una funzione di return
. Sono comandi integrati. Non sono nemmeno parole riservate.
exit
terminare il processo corrente ; con o senza codice di uscita, considera questo un sistema più che una funzione di programma. Si noti che durante l'approvvigionamento, exit
la shell terminerà, tuttavia, quando in esecuzione sarà solo exit
lo script.
return
da una funzione tornare all'istruzione dopo la chiamata, con o senza un codice di ritorno. return
è facoltativo ed è implicito alla fine della funzione. return
può essere utilizzato solo all'interno di una funzione.
Voglio aggiungere che, pur essendo di provenienza, non è facile per exit
lo script all'interno di una funzione senza uccidere la shell. Penso che un esempio sia migliore in uno script "test"
#!/bin/bash
function die(){
echo ${1:=Something terrible wrong happen}
#... clean your trash
exit 1
}
[ -f /whatever/ ] || die "whatever is not available"
# now we can proceed
echo "continue"
facendo quanto segue:
user$ ./test
Whatever is not available
user$
test
- e - la shell si chiuderà.
user$ . ./test
Whatever is not available
solo test
finirà e il prompt mostrerà.
La soluzione è racchiudere la potenziale procedura in (
e)
#!/bin/bash
function die(){
echo $(1:=Something terrible wrong happen)
#... clean your trash
exit 1
}
( # added
[ -f /whatever/ ] || die "whatever is not available"
# now we can proceed
echo "continue"
) # added
ora, in entrambi i casi, test
uscirà solo .
(
e )
inserisce quel blocco in una sotto-shell, annullando effettivamente il .
comando (source) come se avessi eseguito normalmente lo script di test, che si trova in una sotto-shell. IO se lo script non viene eseguito .
o source
allora hai effettivamente 2 sub-shell.
La domanda del PO: Qual è la differenza tra l'istruzione return e exit nelle funzioni BASH rispetto ai codici d'uscita?
In breve, sono necessari alcuni chiarimenti:
Nell'elenco elenco sopra, scegliere tra "(x | y)" o sempre il primo elemento o sempre il secondo elemento per ottenere rispettivamente istruzioni su funzioni e ritorno o shell e uscita.
Ciò che è chiaro è che entrambi condividono l'uso comune della variabile speciale $? per passare valori verso l'alto dopo che terminano.
* Ora per i modi speciali che $? può essere impostato:
Vale la pena notare che $? può essere assegnato un valore chiamando exit in una sub shell, in questo modo:
# (exit 259)
# echo $?
3
exit 259
echo come 3
perché il valore finale di uscita è un singolo byte. 259 % 256 = 3
Prima di tutto, return
è una parola chiave e il exit
mio amico è una funzione.
Detto questo, ecco una spiegazione più semplice.
return
Restituisce un valore da una funzione.
exit
Esce o abbandona la shell corrente.
return
è una parola chiave. Il ritorno è molto più di un semplice codice di uscita, motivo per cui il confronto non è corretto.
exit
né return
"parole chiave", né, come le chiama il manuale bash, "parole riservate". Nessuno dei due è una "funzione", nel senso di una funzione bash. Entrambi sono comandi integrati, in gergo bash. ( V'è una funzione di libreria C standard chiamato exit()
, e il linguaggio di programmazione C ha una parola riservata return
, ma questi non devono essere confuse con i comandi bash, anche se i loro semantica è curiosamente simile.)
help <command>
tua shell per ottenere informazioni su cosa farà un built-in della shell. Nel tuo casohelp return
ehelp exit