Ich habe dies auf der Github-Problemliste gefunden und ich denke, dies beantwortet Ihre Frage wirklich.
Es ist nicht wirklich ein SSH-Problem, es ist eher das subtile Verhalten um nicht interaktive / interaktive BASH-Modi und die Signalweitergabe an Prozessgruppen.
Das Folgende basiert auf
/programming/14679178/why-does-ssh-wait-for-my-subshells-without-t-and-kill-them-with-t/14866774#14866774
und http: //www.itp.uzh.ch/~dpotter/howto/daemonize , mit einigen Annahmen, die nicht vollständig validiert sind, aber Tests, wie dies funktioniert, scheinen dies zu bestätigen.
pty / tty = false
Die gestartete Bash-Shell stellt eine Verbindung zu stdout / stderr / stdin des gestarteten Prozesses her und wird solange ausgeführt, bis nichts mehr mit den Sockets verbunden ist und die untergeordneten Elemente beendet wurden. Ein guter Deamon-Prozess stellt sicher, dass nicht darauf gewartet wird, dass die untergeordneten Prozesse beendet werden. In diesem Modus wird von SSH kein SIGHUP an den untergeordneten Prozess gesendet. Ich glaube, dass dies für die meisten Skripte, die einen Prozess ausführen, der die Desaminierung selbst erledigt und nicht im Hintergrund ausgeführt werden muss, korrekt funktioniert. Wenn Init-Skripte '&' zum Hintergrund eines Prozesses verwenden, ist es wahrscheinlich, dass das Hauptproblem darin besteht, ob der Hintergrundprozess jemals versucht, von stdin zu lesen, da dies ein SIGHUP auslöst, wenn die Sitzung beendet wurde.
pty / tty = true *
Wenn das Init-Skript den Prozess im Hintergrund startet, gibt die übergeordnete BASH-Shell einen Exit-Code an die SSH-Verbindung zurück, der sofort beendet wird, da nicht darauf gewartet wird, dass ein untergeordneter Prozess beendet wird, und nicht auf stdout blockiert wird / stderr / stdin. Dadurch wird ein SIGHUP an die übergeordnete Bash-Shell-Prozessgruppe gesendet, die die gerade gestarteten untergeordneten Prozesse enthält, da die Jobsteuerung in Bash im nicht interaktiven Modus deaktiviert ist. Wenn ein Daemon-Prozess beim Forken oder im Fork-Prozess explizit eine neue Prozesssitzung startet, erhalten er oder seine untergeordneten Prozesse das SIGHUP nicht, wenn der übergeordnete BASH-Prozess beendet wird. Beachten Sie, dass dies anders ist als bei unterbrochenen Jobs, bei denen ein SIGTERM angezeigt wird. Ich vermute, die Probleme, die damit verbunden sind, haben manchmal nur mit einer leichten Rennbedingung zu tun.
http://www.itp.uzh.ch/~dpotter/howto/daemonize , Sie werden sehen, dass im Code die neue Sitzung durch den Fork-Prozess erstellt wird, der möglicherweise nicht ausgeführt wird, bevor das übergeordnete Programm beendet wird Erfolgs- / Misserfolgsverhalten wie oben erwähnt. Eine Sleep-Anweisung lässt genügend Zeit, damit der Fork-Prozess eine neue Sitzung erstellt, weshalb dies in einigen Fällen funktioniert.
pty / tty = true und die Auftragssteuerung wird in bash explizit aktiviert
SSH stellt keine Verbindung zu stdout / stderr / stdin der Bash-Shell oder zu gestarteten untergeordneten Prozessen her. Dies bedeutet, dass es beendet wird, sobald die übergeordnete Bash-Shell die Ausführung der angeforderten Befehle beendet hat. In diesem Fall werden bei expliziter Aktivierung der Jobsteuerung alle Prozesse, die von der Bash-Shell mit '&' im Hintergrund gestartet werden, sofort in eine separate Sitzung versetzt und erhalten kein SIGHUP-Signal, wenn der übergeordnete Prozess zur BASH-Sitzung beendet wird ( SSH-Verbindung in diesem Fall).
Was ist zu beheben
Ich denke, die Lösungen müssen nur explizit in der run / sudo-Betriebsdokumentation als Sonderfall erwähnt werden, wenn mit Hintergrundprozessen / -diensten gearbeitet wird. Verwenden Sie grundsätzlich entweder 'pty = false' oder aktivieren Sie die Jobsteuerung explizit als ersten Befehl, wenn dies nicht möglich ist. Das Verhalten ist dann korrekt.
tomcat/bin/startup.sh
mitfg
/ zusammenbg
?