2012-10-21 12 views
29

Sto cercando di rinforzare il mio script di notifica. Il modo in cui lo script funziona è che l'ho messo dietro un comando shell di lunga durata e poi tutti i tipi di notifiche vengono richiamati dopo che è finito lo script di lunga durata.Ottenere il codice di uscita dell'ultimo comando della shell in un altro script

Ad esempio:

sleep 100; my_notify 

Sarebbe bello per ottenere il codice di uscita dello script in esecuzione lungo, il problema è che chiamando my_notify crea un nuovo processo che non ha accesso alla variabile $?.

Confronta:

~ $: ls nonexisting_file; echo "exit code: $?"; echo "PPID: $PPID" 
ls: nonexisting_file: No such file or directory 
exit code: 1 
PPID: 6203 

vs.

~ $: ls nonexisting_file; my_notify  
ls: nonexisting_file: No such file or directory 
exit code: 0 
PPID: 6205 

Lo script my_notify ha la seguente in esso:

#!/bin/sh 
echo "exit code: $?" 
echo "PPID: $PPID" 

Sto cercando un modo per ottenere il codice di uscita il comando precedente senza modificare troppo la struttura del comando. Sono consapevole del fatto che se lo cambio funzionasse più come time, ad es. my_notify longrunning_command... il mio problema sarebbe risolto, ma in realtà mi piace poterlo attaccare alla fine di un comando e temo complicazioni di questa seconda soluzione.

Questo può essere fatto o è fondamentalmente incompatibile con il modo in cui funzionano le shell?

Il mio guscio è zsh ma mi piacerebbe che funzionasse anche con bash.

risposta

31

Avresti davvero bisogno di usare una funzione di shell per ottenere ciò. Per uno script semplice come quello dovrebbe essere abbastanza facile farlo funzionare sia in zsh che in bash. È sufficiente inserire quanto segue in un file:

my_notify() { 
    echo "exit code: $?" 
    echo "PPID: $PPID" 
} 

Quindi cercare il file dai file di avvio della shell. Anche se dal momento che sarebbe eseguito dalla tua shell interattiva, potresti voler utilizzare $$ piuttosto che $ PPID.

6

Non è compatibile. $?solo esiste all'interno della shell corrente; se lo si desidera disponibile nei sottoprocessi, è necessario copiarlo in una variabile di ambiente.

L'alternativa è scrivere una funzione di shell che la utilizza in qualche modo.

2

Un metodo per implementare questo potrebbe essere l'uso di tag EOF e uno script master che creerà il tuo script my_notify.


#!/bin/bash 

if [ -f my_notify ] ; then 
rm -rf my_notify 
fi 

if [ -f my_temp ] ; then 
rm -rf my_temp 
fi 

retval=`ls non_existent_file &> /dev/null ; echo $?` 
ppid=$PPID 
echo "retval=$retval" 
echo "ppid=$ppid" 
cat >> my_notify << 'EOF' 
#!/bin/bash 

echo "exit code: $retval" 
echo " PPID =$ppid" 
EOF 

sh my_notify 

Si può delimitare questo script per il vostro scopo.