it-swarm.com.de

So verhindern Sie, dass ein Hintergrundprozess nach dem Schließen des SSH-Clients unter Linux gestoppt wird

Ich arbeite auf einem Linux-Rechner über SSH (PuTTY). Ich muss einen Prozess während der Nacht laufen lassen, also dachte ich, ich könnte das tun, indem ich den Prozess im Hintergrund starte (mit einem kaufmännischen Und am Ende des Befehls) und stdout in eine Datei umleite.

Zu meiner Überraschung funktioniert das nicht. Sobald ich das PuTTY-Fenster schließe, wird der Vorgang abgebrochen.

Wie kann ich das verhindern?

280
GetFree

Schauen Sie sich das Programm " Nohup " an.

297
JesperE

Ich würde die Verwendung von GNU-Bildschirm empfehlen. Sie können die Verbindung zum Server trennen, während alle Prozesse ausgeführt werden. Ich weiß nicht, wie ich ohne es gelebt habe, bevor ich wusste, dass es existiert.

163
gpojd

Wenn die Sitzung geschlossen ist, empfängt der Prozess das SIGHUP-Signal, das er anscheinend nicht abfängt. Sie können den Befehl Nohup verwenden, um den Prozess zu starten, oder den integrierten Bash-Befehl disown -h nach dem Start des Prozesses, um dies zu verhindern:

> help disown
disown: disown [-h] [-ar] [jobspec ...]
     By default, removes each JOBSPEC argument from the table of active jobs.
    If the -h option is given, the job is not removed from the table, but is
    marked so that SIGHUP is not sent to the job if the Shell receives a
    SIGHUP.  The -a option, when JOBSPEC is not supplied, means to remove all
    jobs from the job table; the -r option means to remove only running jobs.
79
Robert Gamble

dämonisieren? nein? BILDSCHIRM? (tmux ftw, Bildschirm ist Müll ;-)

Mach einfach das, was jede andere App von Anfang an getan hat - Double Fork.

# ((exec sleep 30)&)
# grep PPid /proc/`pgrep sleep`/status
PPid:   1
# jobs
# disown
bash: disown: current: no such job

Knall! Fertig :-) Ich habe dies unzählige Male auf allen Arten von Apps und vielen alten Maschinen verwendet. Sie können mit Weiterleitungen und so weiter kombinieren, um einen privaten Kanal zwischen Ihnen und dem Prozess zu öffnen.

Als coproc.sh erstellen:

#!/bin/bash

IFS=

run_in_coproc () {
    echo "coproc[$1] -> main"
    read -r; echo $REPLY
}

# dynamic-coprocess-generator. Nice.
_coproc () {
    local i o e n=${1//[^A-Za-z0-9_]}; shift
    exec {i}<> <(:) {o}<> >(:) {e}<> >(:)
. /dev/stdin <<COPROC "${@}"
    (("\[email protected]")&) <&$i >&$o 2>&$e
    $n=( $o $i $e )
COPROC
}

# pi-rads-of-awesome?
for x in {0..5}; do
    _coproc COPROC$x run_in_coproc $x
    declare -p COPROC$x
done

for x in COPROC{0..5}; do
. /dev/stdin <<RUN
    read -r -u \${$x[0]}; echo \$REPLY
    echo "$x <- main" >&\${$x[1]}
    read -r -u \${$x[0]}; echo \$REPLY
RUN
done

und dann

# ./coproc.sh 
declare -a COPROC0='([0]="21" [1]="16" [2]="23")'
declare -a COPROC1='([0]="24" [1]="19" [2]="26")'
declare -a COPROC2='([0]="27" [1]="22" [2]="29")'
declare -a COPROC3='([0]="30" [1]="25" [2]="32")'
declare -a COPROC4='([0]="33" [1]="28" [2]="35")'
declare -a COPROC5='([0]="36" [1]="31" [2]="38")'
coproc[0] -> main
COPROC0 <- main
coproc[1] -> main
COPROC1 <- main
coproc[2] -> main
COPROC2 <- main
coproc[3] -> main
COPROC3 <- main
coproc[4] -> main
COPROC4 <- main
coproc[5] -> main
COPROC5 <- main

Und los gehts, laich was auch immer. Das <(:) öffnet eine anonyme Pipe über die Prozessersetzung, die abbricht, aber die Pipe bleibt bestehen, weil Sie ein Handle dafür haben. Ich mache normalerweise ein sleep 1 anstatt : weil es etwas rassig ist und ich einen "file busy" -Fehler bekomme - passiert nie, wenn ein echter Befehl ausgeführt wird (zB command true)

"heredoc sourcing":

. /dev/stdin <<EOF
[...]
EOF

Dies funktioniert auf jeder einzelnen Shell, die ich jemals ausprobiert habe, einschließlich busybox/etc (initramfs). Ich habe es noch nie zuvor gesehen. Ich habe es unabhängig entdeckt, als ich gestoßen bin. Wer wusste, dass die Quelle Argumente akzeptieren kann? Aber es dient oft als eine viel handlichere Form der Auswertung, wenn es so etwas gibt.

38
anthonyrisinger
Nohup blah &

Ersetzen Sie blah durch Ihren Prozessnamen!

34
Brian Knoblauch

Ich persönlich mag den Befehl 'batch'.

$ batch
> mycommand -x arg1 -y arg2 -z arg3
> ^D

Dadurch wird es in den Hintergrund verschoben und die Ergebnisse werden an Sie gesendet. Es ist ein Teil von Cron.

17
Will Hartung

Wie bereits erwähnt, muss sich der Hintergrundprozess ordnungsgemäß von seinem steuernden Terminal trennen, um einen Prozess im Hintergrund ausführen zu können, damit Sie die Verbindung zu Ihrer SSH-Sitzung trennen können. Dies ist die Pseudotype, die von der SSH-Sitzung verwendet wird.

Informationen zur Dämonisierung von Prozessen finden Sie in Büchern wie Stevens '"Advanced Network Program, Vol. 1, 3rd Edn" oder Rochkinds "Advanced Unix Programming".

Ich musste mich vor kurzem (in den letzten Jahren) mit einem widerspenstigen Programm auseinandersetzen, das sich nicht richtig dämonisierte. Zum Schluss habe ich ein generisches Dämonisierungsprogramm erstellt - ähnlich wie Nohup, aber mit mehr verfügbaren Steuerelementen.

Usage: daemonize [-abchptxV][-d dir][-e err][-i in][-o out][-s sigs][-k fds][-m umask] -- command [args...]
  -V          print version and exit
  -a          output files in append mode (O_APPEND)
  -b          both output and error go to output file
  -c          create output files (O_CREAT)
  -d dir      change to given directory
  -e file     error file (standard error - /dev/null)
  -h          print help and exit
  -i file     input file (standard input - /dev/null)
  -k fd-list  keep file descriptors listed open
  -m umask    set umask (octal)
  -o file     output file (standard output - /dev/null)
  -s sig-list ignore signal numbers
  -t          truncate output files (O_TRUNC)
  -p          print daemon PID on original stdout
  -x          output files must be new (O_EXCL)

Der Doppelstrich ist auf Systemen optional, die nicht die Funktion GNU getopt () verwenden; er ist unter Linux usw. erforderlich (oder Sie müssen POSIXLY_CORRECT in der Umgebung angeben). Da der Doppelstrich überall funktioniert ist es am besten, es zu verwenden.

Sie können mich weiterhin kontaktieren (Vorname Punkt Nachname bei Google Mail Punkt com), wenn Sie die Quelle für daemonize möchten.

Der Code ist jetzt (endlich) auf GitHub in meinem SOQ (Stack Overflow Questions) -Repository als Datei daemonize-1.10.tgz Im - verfügbar. Pakete Unterverzeichnis.

11

Auf einem Debian-basierten System (auf dem entfernten Rechner) installieren Sie:

Sudo apt-get install tmux

Verwendungszweck:

tmux

führen Sie die gewünschten Befehle aus

So benennen Sie eine Sitzung um:

Strg + B dann $

name einsetzen

So beenden Sie die Sitzung:

Strg + B dann D

(Dies verlässt die tmux-Sitzung). Anschließend können Sie sich von SSH abmelden.

Wenn Sie zurückkommen/es erneut überprüfen müssen, starten Sie SSH und geben Sie ein

tmux füge session_name an

Sie kehren dann zu Ihrer tmux-Sitzung zurück.

6
Max

Nohup ist sehr gut, wenn Sie Ihre Daten in einer Datei protokollieren möchten. Aber wenn es in den Hintergrund geht, können Sie ihm kein Passwort geben, wenn Ihre Skripte danach fragen. Ich denke, Sie müssen screen versuchen. Es ist ein Dienstprogramm, das Sie mit yum auf Ihrer Linux-Distribution installieren können, zum Beispiel unter CentOS yum install screen greifen Sie dann über PuTTY oder eine andere Software in Ihrem Shell-Typ screen auf Ihren Server zu. Es öffnet sich Bildschirm [0] in PuTTY. Machen Sie Ihre Arbeit. Sie können in derselben PuTTY-Sitzung weitere Bildschirme [1], [2] usw. erstellen.

Grundlegende Befehle, die Sie kennen müssen:

Bildschirm starten

bildschirm


Um c zum nächsten Bildschirm zu gelangen

strg + a + c


Gehen Sie zu n ext Bildschirm, den Sie erstellt haben

strg + a + n


Bis d etach

strg + a + d


Während der Arbeit schließen Sie PuTTY. Und das nächste Mal, wenn Sie sich über PuTTY anmelden

screen -r

So stellen Sie die Verbindung zu Ihrem Bildschirm wieder her und Sie können sehen, dass Ihr Prozess weiterhin auf dem Bildschirm ausgeführt wird. Und um den Bildschirm zu verlassen, geben Sie #exit ein.

Für weitere Details siehe man screen.

5
Adeel Ahmad

Für die meisten Prozesse können Sie mit diesem alten Linux-Befehlszeilentrick eine Pseudodämonisierung durchführen:

# ((mycommand &)&)

Zum Beispiel:

# ((sleep 30 &)&)
# exit

Starten Sie dann ein neues Terminalfenster und:

# ps aux | grep sleep

Wird zeigen, dass sleep 30 läuft noch.

Was Sie getan haben, ist, den Prozess als Kind eines Kindes zu starten, und wenn Sie ihn beenden, wird der Befehl Nohup, der normalerweise den Prozess zum Beenden auslöst, nicht an das Enkelkind weitergereicht und belässt ihn bei ein verwaister Prozess, der noch läuft.

Ich bevorzuge diesen Ansatz "set it and forget it", ohne mich mit Nohup, screen, tmux, I/O-Umleitung oder irgendetwas anderem auseinandersetzen zu müssen.

5
RAM

Nohup lässt zu, dass ein Client-Prozess nicht beendet wird, wenn ein übergeordneter Prozess beendet wird. Dies kann beim Abmelden als Argument dienen. Noch besser noch nutzen:

Nohup /bin/sh -c "echo \$\$ > $pidfile; exec $FOO_BIN $FOO_CONFIG  " > /dev/null

Nohup macht den Prozess, den Sie starten, immun gegen die Beendigung, die Ihre SSH-Sitzung und ihre untergeordneten Prozesse beim Abmelden beenden. Der Befehl, den ich gegeben habe, bietet Ihnen eine Möglichkeit, die PID der Anwendung in einer PID-Datei zu speichern, damit Sie sie später korrekt beenden und den Prozess ausführen können, nachdem Sie sich abgemeldet haben.

5
jcodeninja

Wenn Sie einen Prozess als Root über den Bildschirm ausführen, müssen Sie auf mögliche Angriffe zur Erhöhung der Berechtigungen achten. Wenn Ihr eigenes Konto in irgendeiner Weise kompromittiert wird, gibt es eine direkte Möglichkeit, den gesamten Server zu übernehmen.

Wenn dieser Prozess regelmäßig ausgeführt werden muss und Sie über ausreichende Zugriffsrechte auf dem Server verfügen, ist die Verwendung von cron die bessere Option, um den Job auszuführen. Sie können auch init.d (den Super-Daemon) verwenden, um Ihren Prozess im Hintergrund zu starten, und er kann beendet werden, sobald er abgeschlossen ist.

5
Dana the Sane

Bildschirm verwenden. Es ist sehr einfach zu bedienen und funktioniert wie VNC für Terminals. http://www.bangmoney.org/presentations/screen.html

4
Deon

Fügen Sie diese Zeichenfolge Ihrem Befehl hinzu:> & - 2> & - <& - &. > & - bedeutet enge stdout. 2> & - bedeutet nahe Stderr. <& - bedeutet enge stdin. & bedeutet im Hintergrund laufen. Dies funktioniert auch, um einen Job programmgesteuert über ssh zu starten:

$ ssh myhost 'sleep 30 >&- 2>&- <&- &'
# ssh returns right away, and your sleep job is running remotely
$
2
tbc0

Wenn Sie auch X-Anwendungen ausführen möchten, verwenden Sie xpra zusammen mit "screen".

2
Alexey Shurygin

Es gibt auch den Daemon Befehl des Open-Source-Pakets libslack.

daemon ist ziemlich konfigurierbar und kümmert sich um alle mühsamen Daemon-Dinge wie automatischen Neustart, Protokollierung oder PID-Datei-Behandlung.

2
janv

ich würde auch für Screen-Programm gehen (ich weiß, dass einige1 Antwort Screen war, aber dies ist eine Vervollständigung)

nicht nur die Tatsache, dass &, Strg + ZBG verweigern, Nohup, etc. kann Ihnen eine böse Überraschung geben, dass, wenn Sie sich abmelden, Job immer noch getötet wird (ich weiß nicht warum, aber es ist mir passiert, und es hat nicht gestört Das liegt daran, dass ich auf die Verwendung des Bildschirms umgestiegen bin, aber ich denke, dass eine Anthonyrisinger-Lösung, bei der das doppelte Gabeln das Problem lösen würde, auch einen großen Vorteil gegenüber dem einfachen Hintergrund hat:

screen will background your process without losing interactive control to it

und übrigens ist dies eine frage, die ich niemals stellen würde :) ... ich benutze screen von anfang an, um irgendetwas unter unix zu machen ... ich arbeite (fast) NIEMALS in einer unix/linux-shell ohne startscreen zuerst ... und ich sollte jetzt aufhören, oder ich starte eine endlose Präsentation dessen, was ein guter Bildschirm ist und was du tun kannst ... schau selbst nach, es lohnt sich;)

2
THESorcerer

Unter systemd/Linux ist systemd-run ein nützliches Tool, um sitzungsunabhängige Prozesse zu starten. Hasser werden hassen

1
Eugene Shatsky

Akzeptierte Antworten schlagen die Verwendung von Nohup vor. Ich würde eher vorschlagen, pm2 zu verwenden. Die Verwendung von pm2 anstelle von Nohup bietet viele Vorteile, z. Verwalten Sie Protokolldateien für Anwendungen und vieles mehr. Für mehr Details check this out .

Um pm2 zu installieren, müssen Sie npm herunterladen. Für Debian-basiertes System

Sudo apt-get install npm

und für Redhat

Sudo yum install npm

Oder Sie können diese Anweisung folgen. Nach der Installation npm verwenden Sie es, um pm2 zu installieren

npm install [email protected] -g

Sobald es fertig ist, können Sie Ihre Anwendung durch starten

$ pm2 start app.js              # Start, Daemonize and auto-restart application (Node)
$ pm2 start app.py              # Start, Daemonize and auto-restart application (Python)

Verwenden Sie zur Prozessüberwachung folgende Befehle:

$ pm2 list                      # List all processes started with PM2
$ pm2 monit                     # Display memory and cpu usage of each app
$ pm2 show [app-name]           # Show all informations about application

Verwalten Sie Prozesse entweder mit dem App-Namen oder der Prozess-ID oder verwalten Sie alle Prozesse zusammen:

$ pm2 stop     <app_name|id|'all'|json_conf>
$ pm2 restart  <app_name|id|'all'|json_conf>
$ pm2 delete   <app_name|id|'all'|json_conf>

Protokolldateien finden Sie in

$HOME/.pm2/logs #contain all applications logs

Binäre ausführbare Dateien können auch mit pm2 ausgeführt werden. Sie müssen eine Änderung in der Jason-Datei vornehmen. Ändere das "exec_interpreter" : "node", zu "exec_interpreter" : "none". (siehe Abschnitt Attribute ).

#include <stdio.h>
#include <unistd.h>  //No standard C library
int main(void)
{
    printf("Hello World\n");
    sleep (100);
    printf("Hello World\n");

    return 0;
}

Kompilieren des obigen Codes

gcc -o hello hello.c  

und starte es mit np2 im hintergrund

pm2 start ./hello
1
haccks

Ich habe den Bildschirmbefehl verwendet. Dieser Link enthält Details dazu

https://www.rackaid.com/blog/linux-screen-tutorial-and-how-to/#starting

1