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?):

  1. Ist es möglich?
  2. Der ins Leben gerufen-Server-Server-Prozesses der PID in meinem pidfile sein?
  3. 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
War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top