2009-04-03 17 views
5

Vogliamo creare uno script eseguito ogni notte (uccide e riavvia un processo java). Per questo abbiamo bisogno di catturare il numero del processo (dal momento che potrebbe essere in esecuzione più di un processo java). Il comando seguente è fondamentalmente ciò che useremo per ottenere il numero di processi, probabilmente con un'espressione regolare alla fine del grep. A meno che non vengano visualizzati suggerimenti migliori.Come acquisire il risultato di una chiamata di sistema in una variabile di shell?

root#ps -e |grep 'java' 
18179 pts/0 00:00:43 java 

vogliamo sapere come analizzare l'output sopra e lo fanno in una variabile di shell in modo che possiamo utilizzare il comando kill, come di seguito.

kill -9 ${processid} 
wait 10 

Nota1: Il motivo per cui non è possibile fare affidamento sul normale comando di arresto del servizio è perché i processi a volte non vogliono morire. E dobbiamo usare manualmente il comando kill.

+0

Che mi dici di pkill? –

risposta

4

Ci sono un paio di opzioni per risolvere questo problema. Se stai usando bash, la variabile di shell '$!' conterrà il PID dell'ultimo processo figlio biforcato. Così, dopo l'avvio del programma Java, fare qualcosa di simile:

echo $! > /var/run/my-process.pid 

Poi, dopo lo script di init arresta il processo di Java:

# Get the pidfile. 
pid=$(cat /var/run/my-process.pid) 

# Wait ten seconds to stop our process. 
for count in $(1 2 3 4 5 6 7 8 9 10); do 
    sleep 1 
    cat "/proc/$pid/cmdline" 2>/dev/null | grep -q java 
    test $? -ne 0 && pid="" && break 
done 

# If we haven't stopped, kill the process. 
if [ ! -z "$pid" ]; then 
    echo "Not stopping; terminating with extreme prejudice." 
    kill -9 $pid 
fi 

Assicurarsi di aver tolto la pidfile quando hai finito.

+1

"Prejucide"? È uno scherzo o un errore? –

+0

Ecco cosa succede quando pubblico una risposta prima del caffè del mattino. –

+0

Inoltre, se hai il comando 'seq', puoi fare 'seq 1 10' invece del conteggio manuale. Tuttavia, non è sempre disponibile su tutti i tipi di Linux. –

0

uccidendolo:

ps -e | grep java | cut -f1 -d' ' | xargs kill -9 

memorizzazione PID sul variabile:

export JAVAPID=`ps -e | grep 'java' | cut -f1 -d' '` 

controllando che ha funzionato:

echo $JAVAPID 
3
ps aux | grep java | awk '{print $1}' | xargs kill -9 

Ecco una spiegazione:

ps aux ti dà un elenco di tutti i processi

grep java voi tutti i processi i cui nomi e argomenti della riga di comando contengono la stringa "java"

awk '{print $1}' analizza l'output del comando grep in colonne per spazi e ristampa solo la prima colonna

xargs kill -9 passa ciascuno dei risultati del comando awk come parametri a un comando kill -9

+2

Salta il grep: ps aux | awk '/ java/{print $ 1}' :) – andri

+0

Grazie per il suggerimento; Non conosco abbastanza bene l'awk per aver saputo come farlo. Lascerò la mia risposta perché è più semplice per me capire personalmente, ma sono felice che tu abbia fatto questo suggerimento. –

+1

Non dovresti avere grep -v grep in là per impedirgli di raccogliere il pid di grep (dato che il suo comando contiene la parola java)? –

1

Si può facilmente ottenere il PID o un elenco di PID in una variabile utilizzando apici inversi e taglio (o awk se si preferisce) per recuperare solo il campo PID:

[[email protected] ~]$ ps -e | grep java | cut -d' ' -f1 
12812 
12870 
13008 
13042 
13060 

Nota nell'esempio precedente Ho più processi Java che eseguono quindi i valori multipli.Se si salva questo in una variabile in questo modo:

JAVA_PROCS=`ps -e | grep java | cut -d' ' -f1` 

È possibile scorrere i processi di ucciderli se lo si desidera:

for proc in $JAVA_PROCS; do 
    kill -9 $proc; 
done 

Naturalmente, se si sta solo il recupero di un unico processo, poi c'è non c'è bisogno di iterare e si può solo correre come:

kill -9 $JAVA_PROCS 
1

Se fai quello che lei suggerisce, si può finire per catturare il grep stesso e l'uccisione che (dal momento che il comando grep contiene la stringa Java che si ar e cercando). È possibile aggirare il escludendo grep (utilizzando un altro grep!):

pid=`ps -e | fgrep java | fgrep -v grep | awk '{print $1}'` 
# check pid has a value 
# kill $pid 

Ti potrebbe piacere anche ps -e -opid,args.

Un'alternativa migliore è utilizzare pgrep(1) o pkill(1) se il sistema li ha. Non più tubi, SED, awks, tagli, xargs:

pkill -9 java 
+0

Quasi ho postato la stessa cosa, ma ps -e non elenca gli argomenti cmd (almeno sulla mia casella) quindi non c'è pericolo di catturare accidentalmente il comando 'grep java' nell'output di grep. – Jay

+0

Spot on, Jay, almeno per Linux. Preferisco ancora pkill ma sembra che io sia in minoranza. –

+0

Puoi anche inserire parentesi attorno al primo carattere in grep, come in grep [j] ava Il grep lo vede come un'espressione regolare e cerca un j, ma la riga di comando non corrisponde al modello. :) Mi fa sentire sporco quando lo faccio, ma funziona bene ... – dannysauer

0

io uso qualcosa di simile:

kill $(ps -A | grep java | cut -b 1-5) 
2

Mi rendo conto che è vecchio, ma per quanto riguarda:

pidof java | xargs kill 
Problemi correlati