Come posso staccare un processo da uno script bash?


18

Sto provando a staccare un processo da uno script bash in modo che SIGINT non venga inoltrato al processo quando esco dallo script.

Ho usato direttamente il disowncomando nel terminale, tuttavia in bash, disownnon si ferma l'inoltro di SIGINT. Lo scopo di questo script è di avviare openocd e quindi gdb con una singola chiamata. Poiché lo script non esce mai (sta eseguendo gdb) SIGINT viene comunque inoltrato da gdb a openocd, il che è un problema poiché SIGINT è usato come comando halt in gdb.

Nel terminale sarebbe simile a questo:

$ openocd &    # run openocd demonized
$ disown $!    # disown last pid
$ gdb          # invoke GDB

quando viene invocato sul terminale in questo ordine, SIGINT non viene passato da gdb a openocd. Tuttavia, se la stessa invocazione era in uno script bash, SIGINT viene passato.

Qualsiasi aiuto sarebbe molto apprezzato.

ps questo problema è in OS X ma sto cercando di usare strumenti che sono anche portatili per tutti gli strumenti Unix.


nohupnon è proprio la risposta giusta. Dovresti aggiungere uno pseudocodice o un codice di esempio per mostrare più precisamente ciò che desideri.
Bruce Ediger,

1
Sei aperto all'utilizzo di uno strumento simile screen?
Eric Renouf,

Risposte:


17

Per staccare un processo da uno script bash:

nohup ./process &

Se interrompi il tuo script bash con SIGINT(ctrl + c), o la shell termina l'invio, SIGHUPad esempio, il processo non sarà disturbato e continuerà a funzionare normalmente. stdoutE stderrsarà reindirizzato a un file di log: nohup.out.

Se si desidera eseguire un comando distaccato mentre si è in grado di vedere l'output nel terminale, utilizzare tail:

TEMP_LOG_FILE=tmp.log
> "$TEMP_LOG_FILE"
nohup ./process &> "$TEMP_LOG_FILE" & tail -f "$TEMP_LOG_FILE" &

Perché è nohupnecassario? Qual è la differenza tra nohup COMMAND &e COMMAND &se il tuo obiettivo è solo quello di eseguire il comando in background e liberare il terminale?
James Wierzba,

@JamesWierzba Una delle differenze è che se hai bisogno del comando per continuare a funzionare anche dopo essere uscito dalla shell, allora nohup è la strada da percorrere. Ci sono migliaia di ampie spiegazioni nel web. Ad esempio stackoverflow.com/questions/15595374/…
marc


4

La soluzione che ho trovato prevede un programma chiamato "staccare" scritto da Annon Inglorion e scaricabile dal suo sito web

Una volta compilato, può essere utilizzato in uno script come segue:

$ ./detach -p debug.pid openocd <args> # detach openocd
$ gdb <args>                           # run gdb
$ kill -9 $(cat debug.pid)             # end openocd process
$ rm debug.pid                         # remove file containing process id

Questa prima riga crea un nuovo processo (eseguendo openocd) e memorizza l'id del processo nel file (debug.pid) per usarlo in seguito. Questo evita i problemi con il grepping per il pid come indicato nella risposta di Oliver. All'uscita dal programma di blocco successivo (gdb), il file che memorizza il pid viene utilizzato per terminare direttamente il processo disconnesso.


Posso confermare, detachfa miracoli.
AS

2

una soluzione semplice e portatile:

echo "openocd" | at now #openocd starts now, but via the at daemon, not the current shell!
pid=$(ps -ef | grep "[o]penocd" | awk '{print $1}')  
echo "openocd is running with pid: $pid"
gdb

Alcuni avvertimenti sulla portabilità: le psopzioni dipendono dal sistema operativo! si potrebbe invece utilizzare una variante di: { ps -ef || ps aux ;} | grep '[o]penocd | cut -f 1. atnon potrebbe essere disponibile (strano, ma questo succede ...). $(...)ha bisogno di una shell non molto vecchia, altrimenti usa i backtick.


Questo sembra pericoloso, il grepping per pid può fare cose inaspettate se più di un processo è in esecuzione con lo stesso nome, o anche, se un altro processo contiene la parola openocd.
Orione,

1
@orion: do un semplice esempio per dare le idee, quelle preoccupazioni che menzioni sono facili da eliminare: avere atuno script che avvia il programma e ne distribuisce il pid invece in un file, e attendere che lo script principale lo attenda file da visualizzare e quindi leggere il pid da esso.
Olivier Dulac il

ovviamente dovresti sostituire nel mio esempio (troppo semplice) il grep con un test all'interno di awk, sulla colonna di destra ($ 8, di solito) (le colonne dipendono dal tuo sistema operativo e dalla versione / opzioni di ps)
Olivier Dulac
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.