Wie PID eines Strich-exec Befehl finden
-
26-09-2019 - |
Frage
. HINWEIS: Ich dachte, ich schlag wurde mit, aber / bin / sh ist mit / bin / dash, die diese seltsame exec Problem hat
Ich habe einen einfachen Bash-Shell-Skript auf Linux, die verwendet wird, einen Server-Prozess zu starten (was ich nicht schreiben oder Kontrolle) und möchte die Bash-Shell-Skript ausgegeben haben, die PID des gestarteten Prozesses zu einem pidfile.
Das Problem ist, dass bash-Befehl exec ersetzt nicht seinen eigenen Prozess mit dem Start-Server-Prozess!
So:
echo $$ | cat > /var/run/launched-server.pid
Dies gilt nicht Arbeit, weil die pid in der Datei, die von bash sein wird, nicht der Server-Prozess. Und wenn der Server-Prozess beendet Bash nicht das dumme Startskript beenden kann in der Prozessliste hängen bleibt.
Hat jemand einen Weg zu verwenden bash wissen, so dass (oder dash vielleicht?):
- Ist es möglich?
- Der ins Leben gerufen-Server-Server-Prozesses der PID in meinem pidfile sein?
- Stellen Sie sicher, dass der Bash-Skript sterben wird, wenn der Start-Server vorhanden und läßt nicht aufgelöste Shell Prozesse in der Prozessliste hängen?
Edit: Dieser Ausschnitt aus dem bash Referenzhandbuch von Nutzen sein ...
exec
exec [-cl] [-a name] [command [arguments]]
Wenn Befehl geliefert wird, ersetzt er die Schale, ohne einen neuen Prozess. Wenn die Option -l geliefert wird, stellt die Schale einen Strich am Anfang des nullten Arguments Befehl übergeben. Dies ist, was das Login-Programm der Fall ist. Die Option -c Ursachen Befehl mit einer leeren Umgebung ausgeführt werden. Wenn -a zugeführt wird, übergibt die Schale Namen als Argument nullten Befehl. Wenn kein Befehl angegeben wird, können Umleitungen verwendet werden, um die aktuelle Shell-Umgebung zu beeinflussen. Wenn es keine Umleitung Fehler vorhanden sind, ist der Rückgabestatus Null; andernfalls der Rückgabestatus ungleich Null ist.
Edit 2: Dies ist das Skript (hygienisiert):
#!/bin/sh
# this is where the server expects to run its services for Daemontools
SERVICE_DIR='/var/service';
# kill stdout, stderr, stdin
exec </dev/null
exec >/dev/null
exec 2>/dev/null
logger -ip daemon.debug -- stdout, stderr, stdin redirected to /dev/null
if [ -d $SERVICE_DIR ]; then
# sanitized...
logger -ip daemon.debug -- services and supervisors exited
else
logger -ip daemon.err -- $SERVICE_DIR does not exist, exiting
exit 1;
fi
if [ -d /var/run/pid ]; then
echo $$ | cat > /var/run/pid/launched-server.pid
logger -ip daemon.debug -- creating launched-server pidfile
fi
# start the server process
logger -ip daemon.info -- launching server on $SERVICE_DIR
exec /usr/local/bin/launched-server
Und einige ps Ausgang vielleicht klarer sein?
me@chainsaw: ~/dev $ ps ax | grep launched-server
13896 pts/1 S+ 0:00 /bin/sh ./server_boot
13905 pts/1 S+ 0:00 launched-server /var/service
13938 pts/2 R+ 0:00 grep --color=auto launched-server
Lösung
Ist Ihre Verteilung start-stop-daemon(8)
enthalten? Herrlich kleines, nützliches Tool wurde speziell für die Start-Daemons von Shell-Skripten gebaut. (Natürlich überleben die Dämonen, den Shell-Skripte, so dass es kein perfektes Spiel sein kann - es hängt davon ab, warum Sie wollen, dass die Shell Ihren Dämon überleben).
Oder etwas einfacher:
Könnte Ihr Problem mit bash exec
Befehl gelöst werden? Er ersetzt den Shell-Prozess mit dem, was Sie gefragt, auszuführen:
#!/bin/bash
echo $$ > /tmp/pidfile
exec /bin/sleep 60
$ ./show_exec.sh
[nothing happens]
Und in einer anderen Shell:
$ cat pidfile
24686
$ ps auxw | grep 24686
sarnold 24686 0.0 0.0 9728 816 pts/1 S+ 04:53 0:00 /bin/sleep 60
Andere Tipps
ich jetzt erkennen, was die real Problem war:
Durch die Verwendung von #!/bin/sh
ich bash nicht aufrufen, aber Strich.
Dash exec ist die Schale mit dem exec Problem. Wenn ich #!/bin/bash
von Anfang an verwendet hätte, wäre es gearbeitet hat, wie erwartet.