Terminare uno script della shell bash in esecuzione in background


16

Uso spesso bashscript di shell per eseguire semplici comandi per molti file diversi. Per esempio, supponiamo che io ho il seguente bashscript di shell, chiamato script.sh, che esegue il comando / programma foosu tre file di testo "a.txt", "b.txt", "c.txt":

#!/bin/bash

for strname in "a" "b" "c"
do
foo $strname".txt"
done

Supponiamo inoltre che foo $strname".txt"sia lento, quindi l'esecuzione dello script richiederà molto tempo (ore o giorni, ad esempio). Per questo motivo, vorrei utilizzarlo in nohupmodo che l'esecuzione continui anche se il terminale è chiuso o disconnesso. Vorrei anche che lo script passasse immediatamente in background, quindi userò l' &operatore. Quindi userò il seguente comando per chiamare script.sh:

nohup bash script.sh &

Questo funziona bene per l'esecuzione dello script in background e senza riaggancio, ma ora supponiamo che vorrei terminare l'esecuzione ad un certo punto per qualche motivo. Come posso fare questo?

Il problema che ho riscontrato è che, guardando top, vedo solo il foocorrispondente "a.txt". Posso terminare quella foochiamata, ma poi viene chiamato il foocorrispondente a "b.txt"e poi devo terminare anche quella, e così via. Per decine o centinaia di file di testo specificati nel forloop, diventa una seccatura terminare ogni foouno a uno! Quindi, in qualche modo, devo invece terminare lo script di shell stesso , non le chiamate particolari emesse dallo script di shell.

Quando scrivo il comando

ps -u myusername

dov'è il myusernamemio nome utente, ottengo un elenco di processi che sto eseguendo. Ma vedo due diversi ID processo chiamati bash. Come faccio a sapere quale di questi processi, se presente, corrisponde alla mia chiamata originale nohup bash script.sh &?


@Andrew, entrambi i processi mostrano nohup menzionato nel comando? .... in alternativa puoi provare ps -aWu Andrew e verificare se trovi una singola voce lunga senza nohup .... ti aiuta?
nitin,

2
A parte questo, il tuo preventivo è stravagante. for s in a b c; do foo "$s".txt; done
Tripleee,

1
@NSD: No, nohupsarà passato da tempo quando apri un elenco dei processi per vedere il lavoro che hai iniziato. Puoi guardare la colonna "gentilezza" psnell'output ma le risposte qui sono più utili.
tripleee,

Risposte:


9

Per impostazione predefinita, psnon mostrerà i parametri con cui è stato chiamato il programma. Le opzioni -fed -lentrambe mostreranno la chiamata completa.

ps -fu username

produrrà un output simile a:

username 23464 66.7  0.0  11400   628 pts/5    R    15:28   1:40 bash script.sh

2
È moderatamente utile, ma non chiarisce in modo chiaro più processi con gli stessi argomenti.
Tripleee,

11

Hai un paio di opzioni. Poiché il processo è in esecuzione in background, è possibile utilizzarlo jobsper trovarlo:

nohup bash script.sh &
...
jobs
[1]+ Running    nohup bash script.sh &
kill %1
jobs
[1]+ Terminated nohup bash script.sh &

È inoltre possibile utilizzare pkillper cercare nella tabella dei processi una corrispondenza della riga di comando; cioè:

pkill -f script.sh

1

L' psoutput (ad es. ps aux) Include l'ID di processo del genitore. Uccidi il genitore bashe anche i suoi figli saranno chiusi.

Per una visualizzazione ASCII dell'albero dei processi, provare pstree -pcon alcuni processi in background in esecuzione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.