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?
Schauen Sie sich das Programm " Nohup " an.
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.
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.
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.
Nohup blah &
Ersetzen Sie blah durch Ihren Prozessnamen!
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.
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.
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.
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
Um c zum nächsten Bildschirm zu gelangen
Gehen Sie zu n ext Bildschirm, den Sie erstellt haben
Bis d etach
Während der Arbeit schließen Sie PuTTY. Und das nächste Mal, wenn Sie sich über PuTTY anmelden
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
.
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.
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.
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.
Bildschirm verwenden. Es ist sehr einfach zu bedienen und funktioniert wie VNC für Terminals. http://www.bangmoney.org/presentations/screen.html
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
$
Wenn Sie auch X-Anwendungen ausführen möchten, verwenden Sie xpra zusammen mit "screen".
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.
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;)
Unter systemd/Linux ist systemd-run ein nützliches Tool, um sitzungsunabhängige Prozesse zu starten. Hasser werden hassen
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
Ich habe den Bildschirmbefehl verwendet. Dieser Link enthält Details dazu
https://www.rackaid.com/blog/linux-screen-tutorial-and-how-to/#starting