#!/bin/bash
function0()
{
local t1=$(exit 1)
echo $t1
}
function0
echo
stampa un valore vuoto. Mi aspettavo:
1
Perché alla t1
variabile non viene assegnato il valore di ritorno del comando exit - 1
?
#!/bin/bash
function0()
{
local t1=$(exit 1)
echo $t1
}
function0
echo
stampa un valore vuoto. Mi aspettavo:
1
Perché alla t1
variabile non viene assegnato il valore di ritorno del comando exit - 1
?
Risposte:
local t1=$(exit 1)
dice alla shell di:
exit 1
in una subshell;t1
, locale alla funzione.È quindi normale che t1
finisca per essere vuoto.
( $()
è noto come sostituzione dei comandi .)
Il codice di uscita è sempre assegnato a $?
, quindi puoi farlo
function0()
{
(exit 1)
echo "$?"
}
per ottenere l'effetto che stai cercando. Ovviamente puoi assegnare $?
ad un'altra variabile:
function0()
{
(exit 1)
local t1=$?
echo "$t1"
}
$(trap 'printf "::ERRNO:$?"' 0; # now do whatever however
Il codice di uscita è stato memorizzato in $? variabile. Utilizzando Command Substitution solo catturare l'output, dovresti usare (...) per creare subshell :
#!/bin/bash
func() {
(exit 1)
local t1=$?
printf '%d\n' "$t1"
}
func
t1=$?
è usarlo, no? e non $?
saresti bloccato dall'operazione di assegnazione? Immagino che sto chiedendo se non dovrebbe essereprintf '%d\n' "${t1}"
In bash
questo funziona:
loc(){ local "x=$(exit "$1"):$?"
printf '$%s:\t%d\n' \
x "${x##*:}" \? "$?"
}
Ha a che fare con l'ordine di valutazione dei comandi e l'assegnazione delle variabili. local
ha un valore di ritorno tutto suo - ed è il comando attualmente in esecuzione, non la sostituzione del comando. La ragione per cui cose come ...
x=$(exit 1); echo "$?"
... can return 1 è perché non c'è mai un ritorno in quel comando tranne che per l'esecuzione della subshell per assegnare $x
il valore - quindi $?
non viene bloccato come praticamente in ogni altro caso in cui vengono usate le sostituzioni di comandi.
In ogni caso, con local
esso non vengono rovinati - ma se si cattura è proprio al momento giusto - che è, mentre le espansioni sono ancora in corso di valutazione e prima di local
's routine hanno la possibilità di clobber - si può ancora assegnare.
unset x; loc 130; echo "${x-\$x is unset}"
... stampe ...
$x: 130
$?: 0
$x is unset
Dovresti sapere però che in molte shell non puoi fare affidamento sull'impostazione della $?
valutazione intermedia in quel modo. In effetti, probabilmente è perché quelle conchiglie non si preoccupano di rivalutare in ogni possibile congiuntura come forse bash
fa - il che direi che probabilmente è un comportamento migliore di quello bash
. Vuoi davvero che il tuo interprete valuti ricorsivamente i valori di valutazione che molto probabilmente saranno sovrascritti prima che tu abbia mai la possibilità di usarli?
Ad ogni modo, è così che puoi farlo.
A seconda del motivo per cui stai solo cercando di ottenere il codice di uscita, puoi anche eseguirlo, il if some-command; then echo "Success $?"; else echo "Failure $?"; fi
che non fa nulla con l'output del comando, ma valuta solo il codice di uscita dell'esecuzione del comando. È possibile aggiungere or
( or
$ ( around the command and you'll still get the same results. A better example might be
se grep -q 'somestring' somefile; quindi echo "Il codice di uscita somestring trovato è $?"; Altrimenti "Il codice di uscita somestring è $?"; Fi`.
Puoi anche testare il codice di ritorno di una funzione che può essere un return 3
codice di ritorno esplicito o implicito che è il risultato dell'ultimo comando, in questo caso devi fare attenzione a non avere un echo
alla fine del funzione, altrimenti maschera / ripristina il precedente codice di uscita.
command_last () {
echo "True is `true`"
echo "False is `false`"
false
}
command_last; echo $?
# Outputs:
# True is 0
# False is 1
# 1
echo_last () {
echo "True is `true`"
echo "False is `false`"
false
# echo'ing literally anything (or nothing) returns true aka exit 0
echo
}
echo_last; echo $?
# Outputs:
# True is 0
# False is 1
# # Blank line due to empty echo
# 0
Finalmente un trucco sporco dal momento che non puoi farlo VAR=(SOME_COMMAND)
perché VAR=()
è una definizione di array, quindi è necessario VAR=( $(echo 'Some value') )
.