it-swarm.com.de

Wie kann ich einen Prozess von einem Bash-Skript trennen?

Ich versuche, einen Prozess von einem Bash-Skript zu trennen, damit SIGINT beim Beenden des Skripts nicht an den Prozess weitergeleitet wird.

Ich habe den Befehl disown direkt im Terminal verwendet, aber in bash verhindert disown nicht, dass SIGINT weitergeleitet wird. Der Zweck dieses Skripts besteht darin, openocd und dann gdb mit einem einzigen Aufruf zu starten. Da das Skript nie beendet wird (es führt gdb aus), wird SIGINT immer noch von gdb an openocd weitergeleitet, was ein Problem darstellt, da SIGINT als Halt-Befehl in gdb verwendet wird.

Im Terminal würde es ungefähr so ​​aussehen:

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

wenn der SIGINT in dieser Reihenfolge auf dem Terminal aufgerufen wird, wird er nicht von gdb an openocd übergeben. Wenn sich derselbe Aufruf jedoch in einem Bash-Skript befand, wird SIGINT übergeben.

Jede Hilfe wäre sehr dankbar.

ps Dieses Problem tritt in OS X auf, aber ich versuche, Tools zu verwenden, die auch auf alle Unix-Tools portierbar sind.

19
user2328113

So trennen Sie einen Prozess von einem Bash-Skript:

Nohup ./process &

Wenn Sie Ihr Bash-Skript mit SIGINT (Strg + c) stoppen oder die Shell beispielsweise das Senden von SIGHUP beendet, wird der Prozess nicht gestört und weiterhin normal ausgeführt. stdout & stderr wird in eine Protokolldatei umgeleitet: Nohup.out.

Wenn Sie einen getrennten Befehl ausführen möchten, während Sie die Ausgabe im Terminal sehen können, verwenden Sie tail:

TEMP_LOG_FILE=tmp.log
> "$TEMP_LOG_FILE"
Nohup ./process &> "$TEMP_LOG_FILE" & tail -f "$TEMP_LOG_FILE" &
16
marc

Für mich funktioniert das perfekt mit Verleugnung

command & disown
12
ManuelSchneid3r

Die Lösung, die ich gefunden habe, beinhaltet ein Programm namens "Detach", das von Annon Inglorion geschrieben und von seiner Website heruntergeladen werden kann

Einmal kompiliert, kann es wie folgt in einem Skript verwendet werden:

$ ./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

Diese erste Zeile erstellt einen neuen Prozess (mit openocd) und speichert die Prozess-ID in einer Datei (debug.pid) zur späteren Verwendung. Dies verhindert die Probleme beim Greifen nach der PID, wie in Olivers Antwort angegeben. Beim Beenden des nächsten Blockierungsprogramms (gdb) wird die Datei, in der die PID gespeichert ist, verwendet, um den getrennten Prozess direkt abzubrechen.

4
user2328113

eine einfache und tragbare Lösung:

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

Einige Einschränkungen hinsichtlich der Portabilität: ps Optionen hängen vom Betriebssystem ab! Sie könnten stattdessen eine Variante von verwenden: { ps -ef || ps aux ;} | grep '[o]penocd | cut -f 1. at konnte nicht verfügbar sein (seltsam, aber das passiert ...). $(...) benötigt eine nicht wirklich alte Shell, andernfalls verwenden Sie Backticks.

2
Olivier Dulac