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


291

Ich arbeite auf einem Linux-Computer über SSH (Putty). Ich muss einen Prozess nachts 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 umleitet.

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

Wie kann ich das verhindern?

Antworten:


301

Schauen Sie sich das Programm " nohup " an.


4
Wie stoppen Sie es danach?
Derek Dahmer

9
Melden Sie sich an und führen Sie "kill <pid>" aus. Verwenden Sie "pidof", wenn Sie die pid nicht kennen.
JesperE

32
Sie können verwenden nohup command > /dev/null 2>&1 &, um im Hintergrund auszuführen, ohne eine stdout- oder stderr-Ausgabe (keine nohup.outDatei) zu erstellen
KCD

Was ist, wenn ich etwas eingeben muss? Zum Beispiel habe ich ein Skript mit langer Laufzeit, das ich im Hintergrund ausführen muss, aber zuerst nach meinem FTP-Passwort fragt. nohuphilft in diesem Fall nicht. Gibt es eine Möglichkeit, mit Ctrl+Z/ zu fummeln bg?
Sergey

1
Da ich faul und schlecht darin bin, kryptische Zeichenfolgen auswendig zu lernen, habe ich dies auf der Grundlage der Aussagen von @KCD geschrieben und es häufig verwendet.
Anomalie

167

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


7
Dies ist eine der größten Software, die ich je verwendet habe. Ernsthaft. Ich habe es auf einer BSD-Box, in die ich von ÜBERALL aus ssh kann, und kann es einfach wieder an meinen Bildschirm anschließen und alle meine Terminals haben, an denen ich alle möglichen Dinge mache.
Adam Jaskiewicz

1
Ich kann das bezeugen. Bildschirm ist eine großartige Anwendung. Die Möglichkeit zum erneuten Anbringen ist erstaunlich und spart eine Menge potenziell verlorener Arbeit.
Willasaywhat

Ich verwende es sogar auf lokalen Computern und hänge mehrere xterms an dieselbe Bildschirmsitzung an (Bildschirm -x). Auf diese Weise kann ich viele Fenster in meiner Bildschirmsitzung öffnen und meine verschiedenen xterms frei von Fenster zu Fenster wechseln.
Adam Jaskiewicz

17
Hängt davon ab, ob Sie erneut eine Verbindung zur Hintergrund-App herstellen müssen oder nicht. Wenn Sie dies tun, ist der Bildschirm die einzige Möglichkeit zu fliegen. Wenn es jedoch Feuer und Vergessen ist, dann passt nohup genauso gut, wenn nicht sogar besser.
Dave Sherohman

1
+1 für Bildschirm. Oder als Alternative tmux (ich mag dieses mehr als Bildschirm) oder sogar byobu, was ein schönes Frontend für Bildschirm oder tmux ist. Sie können einfach screen eingeben, um eine Shell zu verwenden und später jederzeit zurückzukehren, oder Ihren Befehl mit screen ausführen, z. B. "screen command": Die Bildschirmsitzung bleibt bestehen, solange der Prozess "command" vorhanden ist und falls dies der Fall ist Sehr lange können Sie jederzeit zurückgehen und die Standardausgabe anzeigen.
Gerlos

81

Wenn die Sitzung geschlossen ist, empfängt der Prozess das SIGHUP-Signal, das er anscheinend nicht abfängt. Sie können den nohupBefehl beim Starten des Prozesses oder den integrierten Befehl bash disown -hnach dem Starten des Prozesses verwenden, 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.

4
Vorteil hierbei ist, dass Disown für Prozesse funktioniert, die bereits gestartet wurden.
Christian K.

1
Bedeutet "Jobspezifikation" die PID?
Stewart

1
Keine Sorge, diese Antwort finden Sie hier stackoverflow.com/questions/625409/…
Stewart

42

dämonisieren? nein? BILDSCHIRM? (tmux ftw, Bildschirm ist Junk ;-)

Tun Sie 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 "${@}"
    (("\$@")&) <&$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 geht's, laiche was auch immer. Das <(:) öffnet eine anonyme Pipe durch Prozessersetzung, die stirbt, aber die Pipe bleibt bestehen, weil Sie ein Handle dafür haben. Normalerweise mache ich ein sleep 1statt, :weil es etwas rassig ist und ich einen "Datei beschäftigt" -Fehler bekomme - passiert nie, wenn ein echter Befehl ausgeführt wird (z. B. 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 stupste. Wer wusste, dass die Quelle Argumente akzeptieren kann? Aber es dient oft als viel besser handhabbare Form der Bewertung, wenn es so etwas gibt.


2
warum die Abwahl ... also was ist, wenn die Frage alt ist; Es ist offensichtlich relevant, wenn man bedenkt, dass es 11 andere Antworten gibt, die scheiße sind. Diese Lösung ist ohne System die idiomatische und akzeptierte Art, in den letzten 30 Jahren zu dämonisieren, nicht sinnlose Apps, z. nohup et al.
Anthonyrisinger

7
Egal wie gut Ihre Antwort ist, manchmal wird es jemandem auf SO nicht gefallen und er wird abstimmen. Es ist besser, sich nicht zu viele Sorgen zu machen.
Alex D

1
@ tbc0 ... versuchenssh myhost "((exec sleep 500)&) >/dev/null"
Anthonyrisinger

1
@anthonyrisinger ok, das funktioniert. Ich denke das ist sauberer: ssh myhost 'sleep 500 >&- 2>&- <&- &' TMTOWTDI;)
tbc0

1
Das ist toll. Die einzige Lösung, die tatsächlich in der Busybox funktioniert. es verdient mehr positive Stimmen
Hamy

34
nohup blah &

Ersetzen Sie bla durch Ihren Prozessnamen!


2
Möglicherweise möchten Sie Umleitungsstandardausgang und Standardfehler hinzufügen.
David Nehme

9
nohup leitet stdout und stderr zu nohup.out um (oder je nach Version zu nohup.out und nohup.err). Wenn Sie also nicht mehrere Befehle ausführen, ist dies nicht erforderlich.
Chas. Owens

17

Persönlich mag ich den Befehl 'Batch'.

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

Dadurch wird es in den Hintergrund gestellt und die Ergebnisse per E-Mail an Sie gesendet. Es ist ein Teil von Cron.


11

Wie andere angemerkt haben, muss sich der Hintergrundprozess ordnungsgemäß von seinem steuernden Terminal trennen, um einen Prozess im Hintergrund auszuführen, damit Sie die Verbindung zu Ihrer SSH-Sitzung trennen können. Dies ist die Pseudo-Tty, die die SSH-Sitzung verwendet.

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

Ich musste mich kürzlich (in den letzten Jahren) mit einem widerspenstigen Programm befassen, das sich nicht richtig dämonisierte. Am Ende habe ich mich damit befasst, indem ich ein generisches Dämonisierungsprogramm erstellt habe - ähnlich wie bei 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 die GNU-Funktion getopt () nicht verwenden. Es ist unter Linux usw. erforderlich (oder Sie müssen POSIXLY_CORRECT in der Umgebung angeben). Da Double-Dash überall funktioniert, ist es am besten, es zu verwenden.

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

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


13
Warum legst du die Quelle nicht auf Github oder Bitbucket?
Rob

5
Warum rechtfertigt das Fehlen der Quelle von Github eine Ablehnung?
Jonathan Leffler

7
@JonathanLeffler IMHO listet alle coolen Optionen eines Programms auf, das in keiner Form (nicht einmal kommerziell) öffentlich verfügbar ist, und verschwendet nur die Zeit des Lesers.
DepressedDaniel

7

Auf einem Debian-basierten System (auf dem Remote-Computer) Installieren Sie:

sudo apt-get install tmux

Verwendungszweck:

tmux

Führen Sie die gewünschten Befehle aus

So benennen Sie die 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 Sitzungsname hinzu

Sie kehren zu Ihrer tmux-Sitzung zurück.


Dies ist der
richtige

6

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

# ((mycommand &)&)

Beispielsweise:

# ((sleep 30 &)&)
# exit

Starten Sie dann ein neues Terminalfenster und:

# ps aux | grep sleep

Wird zeigen, dass sleep 30noch läuft.

Was Sie getan haben, ist, den Prozess als Kind eines Kindes nohupzu starten , und wenn Sie beenden, wird der Befehl, der normalerweise den Prozess zum Beenden auslösen würde, nicht auf das Enkelkind übertragen, sodass er als verwaister Prozess verbleibt und noch ausgeführt wird .

Ich ziehe dieses „gesetzt und vergessen“ -Ansatz, keine Notwendigkeit zu behandeln nohup, screen, tmux, I / O - Umleitung oder irgendwelchen von diesem Zeug.


5

Wenn Sie den Bildschirm verwenden, um einen Prozess als Root auszuführen, achten Sie auf die Möglichkeit von Angriffen zur Erhöhung von Berechtigungen. Wenn Ihr eigenes Konto irgendwie 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 ausreichenden Zugriff auf den Server verfügen, ist es besser, cron zum Ausführen des Jobs zu verwenden. Sie können auch init.d (den Super-Daemon) verwenden, um Ihren Prozess im Hintergrund zu starten, und er kann beendet werden, sobald er fertig ist.


5

nohupist sehr gut, wenn Sie Ihre Daten in einer Datei protokollieren möchten. Aber wenn es um den Hintergrund geht, können Sie ihm kein Passwort geben, wenn Ihre Skripte danach fragen. Ich denke du musst es versuchen screen. Es ist ein Dienstprogramm, das Sie mit yum beispielsweise unter CentOS auf Ihrer Linux-Distribution installieren und yum install screendann über Putty oder eine andere Software in Ihrem Shell-Typ auf Ihren Server zugreifen können screen. Es öffnet Bildschirm [0] in Kitt. Tun Sie Ihre Arbeit. Sie können in derselben Kitt-Sitzung mehr Bildschirm [1], Bildschirm [2] usw. erstellen.

Grundlegende Befehle, die Sie kennen müssen:

Bildschirm starten

Bildschirm


Um c reate nächsten Bildschirm

Strg + a + c


Um zum n ext Bildschirm erstellt Ihnen

Strg + a + n


Um d Etach

Strg + a + d


Während der Arbeit schließen Sie Ihren Kitt. Und das nächste Mal, wenn Sie sich per Kitt anmelden

Bildschirm -r

Um die Verbindung zu Ihrem Bildschirm wiederherzustellen, können Sie sehen, dass Ihr Prozess noch auf dem Bildschirm ausgeführt wird. Und um den Bildschirm zu verlassen, geben Sie #exit ein.

Weitere Details finden Sie unter man screen.


Die Annahme, dass dies yumdas richtige Werkzeug ist, wenn Sie die Distribution nicht kennen, ist nicht gut. Sie sollten klarstellen, auf welchen Distributionen screeninstalliert werden kann yum.
Tymik

5

Mit Nohup kann ein Client-Prozess nicht beendet werden, wenn der übergeordnete Prozess beendet wird. Dies ist ein Argument, wenn Sie sich abmelden. Noch besser noch verwenden:

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.




2

Ich würde auch für Bildschirmprogramm gehen (ich weiß, dass eine andere Antwort Bildschirm war, aber dies ist eine Vervollständigung)

Nicht nur die Tatsache, dass &, Strg + Z bg Verleugnung, Nohup usw. Sie möglicherweise böse überraschen, dass der Job beim Abmelden immer noch beendet wird (ich weiß nicht warum, aber es ist mir passiert, und es hat mich nicht gestört Das liegt daran, dass ich auf Bildschirm umgestellt habe, aber ich denke, Anthonyrisinger-Lösung als Doppelgabelung würde das lösen.) Auch Bildschirm hat einen großen Vorteil gegenüber nur Hintergrund:

screen will background your process without losing interactive control to it

und übrigens, das ist eine Frage, die ich niemals stellen würde :) ... ich benutze den Bildschirm von Anfang an, um irgendetwas in einem Unix zu tun ... Ich arbeite (fast) NIE in einer Unix / Linux-Shell ohne Startbildschirm zuerst ... und ich sollte jetzt aufhören, oder ich beginne eine endlose Präsentation darüber, was ein guter Bildschirm ist und was für dich tun kann ... schau selbst nach, es lohnt sich;)


PS Anthonyrisinger, du bist gut, das gebe ich dir aber ... 30 Jahre? Ich wette, das ist eine Lösung, wenn &, bg, nohup oder screen noch nicht da waren, und keine Beleidigung. Ich schätze Ihr Wissen, aber das ist viel zu kompliziert, um es zu verwenden :)
THESorcerer

2
(beiseite: siehe Tmux ) Obwohl dies weit vor mir liegt [1987], wurde &(asynchrone Ausführung) 1971 von der Thompson-Shell für die erste Version von UNIX eingeführt ... also war es buchstäblich "immer" ;-) leider, Ich war zu konservativ - es sind tatsächlich 41 Jahre vergangen.
Anthonyrisinger

2

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

daemon ist ziemlich konfigurierbar und kümmert sich um all die mühsamen Daemon-Dinge wie automatischen Neustart, Protokollierung oder Pidfile-Behandlung.


2

Fügen Sie diese Zeichenfolge an Ihren Befehl an:> & - 2> & - <& - &. > & - bedeutet stdout schließen. 2> & - bedeutet stderr schließen. <& - bedeutet nahe 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
$


1

Akzeptierte Antwort schlägt vor, nohup zu verwenden . Ich würde eher die Verwendung von pm2 vorschlagen . Die Verwendung von pm2 über nohup bietet viele Vorteile, z. B. das Aufrechterhalten der Anwendung, das Verwalten von Protokolldateien für die Anwendung und viele weitere Funktionen. Weitere Informationen finden Sie hier .

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 diesen Anweisungen folgen . Nach der Installation von npm verwenden Sie es, um pm2 zu installieren

npm install pm2@latest -g

Sobald dies erledigt ist, können Sie Ihre Bewerbung 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 die folgenden 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. Ändern Sie das "exec_interpreter" : "node"in "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 führen Sie es mit np2 im Hintergrund aus

pm2 start ./hello

Kann dies verwendet werden, um ausführbare Binärdateien auszuführen?
GetFree

@ GetFree; Ja. Sie können.
Haccks

Fügen Sie bitte ein Beispiel hinzu. Die Antwort, wie sie jetzt ist, scheint nur für Skriptdateien gut zu sein.
GetFree

@ GetFree; Das Beispiel wurde hinzugefügt. Lassen Sie mich wissen, wenn Sie ein Problem haben.
Haccks

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.