Je travaille sur une machine Linux via SSH (PuTTY). Je dois laisser un processus en cours d'exécution pendant la nuit. Je pensais donc pouvoir le faire en démarrant le processus en arrière-plan (avec une esperluette à la fin de la commande) et en redirigeant stdout vers un fichier.
À ma grande surprise, ça ne marche pas. Dès que je ferme la fenêtre PuTTY, le processus est arrêté.
Comment puis-je empêcher que cela ne se produise?
Découvrez le programme " Nohup ".
Je recommanderais d'utiliser écran GN . Il vous permet de vous déconnecter du serveur pendant que tous vos processus continuent de s'exécuter. Je ne sais pas comment je vivais sans elle avant de savoir qu'elle existait.
Lorsque la session est fermée, le processus reçoit le signal SIGHUP qu’il ne semble apparemment pas capter. Vous pouvez utiliser la commande Nohup
lors du lancement du processus ou la commande intégrée bash disown -h
après avoir lancé le processus pour éviter que cela ne se produise:
> 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émoniser? nohup? ÉCRAN? (tmux ftw, l'écran est indésirable ;-)
Faites ce que toutes les autres applications ont fait depuis le début - double fork.
# ((exec sleep 30)&)
# grep PPid /proc/`pgrep sleep`/status
PPid: 1
# jobs
# disown
bash: disown: current: no such job
Coup! Fait :-) J'ai utilisé ces innombrables fois sur tous les types d'applications et sur de nombreuses vieilles machines. Vous pouvez combiner avec des redirections et autres actions pour ouvrir un canal privé entre vous et le processus.
Créez en tant que coproc.sh:
#!/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
puis
# ./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
Et voilà, engendrez n'importe quoi. le <(:) ouvre un canal anonyme via la substitution de processus, qui meurt, mais le canal reste collé car vous en avez le contrôle. Je fais habituellement un sleep 1
au lieu de :
parce que c'est un peu rusé, et j'aurais une erreur "fichier occupé" - cela ne se produit jamais si une commande réelle est exécutée (par exemple, command true
)
"sourcing heredoc":
. /dev/stdin <<EOF
[...]
EOF
Cela fonctionne sur tous les Shell que j'ai jamais essayés, y compris busybox/etc (initramfs). Je ne l'ai jamais vu faire auparavant, je l'ai découvert de manière indépendante en poussant, qui savait que la source pouvait accepter les arguments? Mais il s’agit souvent d’une forme d’évaluation beaucoup plus gérable, s’il existe.
Nohup blah &
Remplacez le nom de votre processus par blah!
Personnellement, j'aime bien la commande 'batch'.
$ batch
> mycommand -x arg1 -y arg2 -z arg3
> ^D
Cela le place dans l’arrière-plan, puis vous envoie les résultats par courrier. C'est une partie de cron.
Comme d'autres l'ont noté, pour exécuter un processus en arrière-plan afin de pouvoir vous déconnecter de votre session SSH, le processus d'arrière-plan doit être correctement dissocié de son terminal de contrôle, qui est le pseudo-tty utilisé par la session SSH.
Vous trouverez des informations sur la démonisation de processus dans des ouvrages tels que "Advanced Network Program, Vol 1, 3rd Edn" de Stevens ou "Advanced Unix Programming" de Rochkind.
J'ai récemment (au cours des deux dernières années) dû faire face à un programme récalcitrant qui ne s'est pas démonisé correctement. J'ai fini par gérer cela en créant un programme de démonisation générique - similaire à Nohup mais avec plus de contrôles disponibles.
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)
Le double tiret est facultatif sur les systèmes n'utilisant pas la fonction GNU getopt (); cela est nécessaire (ou vous devez spécifier POSIXLY_CORRECT dans l'environnement) sous Linux, etc. Comme le double tiret fonctionne partout, il est préférable de l'utiliser.
Vous pouvez toujours me contacter (prénom point dernier nom sur gmail point com) si vous souhaitez obtenir le code source de daemonize
.
Cependant, le code est maintenant (enfin) disponible sur GitHub dans mon référentiel SOQ (Stack Overflow Questions) en tant que fichier daemonize-1.10.tgz
dans le sous-répertoire packages .
Sur un système basé sur Debian (sur la machine distante), installez:
Sudo apt-get install tmux
Usage:
tmux
exécuter les commandes que vous voulez
Pour renommer la session:
Ctrl + B alors $
nom du jeu
Pour sortir de la session:
Ctrl + B alors D
(cela quitte la session tmux). Ensuite, vous pouvez vous déconnecter de SSH.
Lorsque vous devez revenir/vérifier à nouveau, démarrez SSH et entrez
tmux attach nom_session
Cela vous ramènera à votre session tmux.
Nohup
est très utile si vous souhaitez enregistrer vos détails dans un fichier. Mais quand il passe en arrière-plan, vous ne pouvez pas lui donner un mot de passe si vos scripts le demandent. Je pense que vous devez essayer screen
. C’est un utilitaire que vous pouvez installer sur votre distribution Linux en utilisant yum, par exemple sous CentOS yum install screen
, puis accédez à votre serveur via PuTTY ou un autre logiciel, dans votre type de shell screen
. Il ouvrira l'écran [0] dans PuTTY. Fais ton travail. Vous pouvez créer plus d'écran [1], d'écran [2], etc. au cours de la même session PuTTY.
Commandes de base à connaître:
Pour démarrer l'écran
Pour c créer l'écran suivant
Pour passer à l'écran n ext que vous avez créé
Pour d etach
Pendant le travail, fermez votre mastic. Et la prochaine fois que vous vous connecterez via le type PuTTY
Pour vous reconnecter à votre écran, vous pouvez voir que votre processus est toujours en cours d'exécution à l'écran. Et pour quitter le type d’écran #exit.
Pour plus de détails, voir man screen
.
Pour la plupart des processus, vous pouvez pseudo-démoniser en utilisant cette vieille astuce de ligne de commande Linux:
# ((mycommand &)&)
Par exemple:
# ((sleep 30 &)&)
# exit
Puis lancez une nouvelle fenêtre de terminal et:
# ps aux | grep sleep
Montre que sleep 30
est toujours en cours d'exécution.
Vous avez démarré le processus en tant qu'enfant d'un enfant et lorsque vous quittez la commande, la commande Nohup
qui déclencherait normalement la fermeture du processus ne se répercute pas en cascade sur le petit-enfant, le laissant ainsi. Processus orphelin, toujours en cours d'exécution.
Je préfère cette approche "installez-le et oubliez-le", pas besoin de vous occuper de Nohup
, screen
, tmux, de la redirection d'E/S ou de tout ce genre de choses.
Nohup permet de ne pas tuer un processus client si le processus parent est tué, comme argument lorsque vous vous déconnectez. Encore mieux utiliser encore:
Nohup /bin/sh -c "echo \$\$ > $pidfile; exec $FOO_BIN $FOO_CONFIG " > /dev/null
Nohup rend le processus que vous démarrez immunisé contre toute interruption de votre session SSH et de ses processus enfants lorsque vous vous déconnectez. La commande que j'ai donnée vous fournit un moyen de stocker le pid de l'application dans un fichier pid afin que vous puissiez le tuer correctement plus tard et permettre l'exécution du processus une fois que vous vous êtes déconnecté.
Si vous utilisez screen pour exécuter un processus en tant que root, prenez garde à la possibilité d'attaques par élévation de privilèges. Si votre compte est compromis d'une manière ou d'une autre, il y aura un moyen direct de prendre en charge l'intégralité du serveur.
Si ce processus doit être exécuté régulièrement et que vous disposez d'un accès suffisant sur le serveur, une meilleure option serait d'utiliser cron l'exécution du travail. Vous pouvez également utiliser init.d (le super démon) pour démarrer votre processus en arrière-plan, qui peut se terminer dès que c'est fait.
Utilisez l'écran. Il est très simple à utiliser et fonctionne comme vnc pour les terminaux. http://www.bangmoney.org/presentations/screen.html
Ajoutez cette chaîne à votre commande:> & - 2> & - <& - &. > & - signifie fermer stdout. 2> & - signifie fermer stderr. <& - signifie fermer stdin. & signifie courir en arrière-plan. Cela fonctionne pour démarrer un travail par programme via ssh également:
$ ssh myhost 'sleep 30 >&- 2>&- <&- &'
# ssh returns right away, and your sleep job is running remotely
$
Si vous souhaitez également exécuter des applications X, utilisez xpra avec "screen".
Il y a aussi la commande daemon du paquet libslack open-source.
daemon
est tout à fait configurable et prend en charge tous les trucs fastidieux du démon tels que le redémarrage automatique, la journalisation ou la gestion du fichier pid.
je voudrais aussi aller pour le programme d'écran (je sais que quelque autre réponse était écran mais c'est une complétion)
non seulement le fait que &, ctrl + z bg désavoué, Nohup, etc. puisse vous donner une vilaine surprise que lorsque vous vous déconnectez, un travail sera toujours tué (je ne sais pas pourquoi, mais cela m'est arrivé et cela ne m'a pas dérangé avec cela soit parce que je suis passé à l’utilisation d’écran, mais je suppose que la solution anthonyrisinger (un double fourrage résoudrait cela), les écrans ont également un avantage majeur par rapport à l’arrière-plan:
screen will background your process without losing interactive control to it
et d'ailleurs, c'est une question que je ne poserais jamais en premier lieu :) ... j'utilise l'écran depuis mon début de rien faire dans n'importe quel unix ... je (presque) ne travaille JAMAIS dans un Shell Unix/Linux sans démarrer l'écran D'abord ... et je devrais m'arrêter maintenant, ou je vais commencer une présentation sans fin de ce qu'est un bon écran et de ce que vous pouvez faire pour vous ... Regardez-le par vous-même, ça vaut le coup;)
Sur systemd/Linux, systemd-run est un outil pratique pour lancer des processus indépendants de la session. Les haineux continueront de détester
La réponse acceptée suggère d'utiliser Nohup . Je suggérerais plutôt d'utiliser pm2 . Utiliser pm2 sur Nohup présente de nombreux avantages, tels que le maintien de l'application en vie, maintenir les fichiers de log pour l'application et beaucoup plus d'autres fonctionnalités. Pour plus de détails cochez cette case .
Pour installer pm2 , vous devez télécharger npm . Pour un système basé sur Debian
Sudo apt-get install npm
et pour Redhat
Sudo yum install npm
Ou vous pouvez suivre ces instructions . Après avoir installé npm , utilisez-le pour installer pm2
npm install pm2@latest -g
Une fois que vous avez terminé, vous pouvez commencer votre application en
$ pm2 start app.js # Start, Daemonize and auto-restart application (Node)
$ pm2 start app.py # Start, Daemonize and auto-restart application (Python)
Pour la surveillance du processus, utilisez les commandes suivantes:
$ 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
Gérez les processus à l'aide du nom de l'application ou de l'ID de processus ou gérez tous les processus ensemble:
$ pm2 stop <app_name|id|'all'|json_conf>
$ pm2 restart <app_name|id|'all'|json_conf>
$ pm2 delete <app_name|id|'all'|json_conf>
Les fichiers de log peuvent être trouvés dans
$HOME/.pm2/logs #contain all applications logs
Les fichiers exécutables binaires peuvent également être exécutés à l’aide de pm2. Vous devez modifier le fichier jason. Changez le "exec_interpreter" : "node"
en "exec_interpreter" : "none".
(voir le section d'attributs ).
#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;
}
Compiler le code ci-dessus
gcc -o hello hello.c
et exécutez-le avec np2 en arrière-plan
pm2 start ./hello
J'ai utilisé la commande d'écran. Ce lien contient des détails sur la manière de procéder.
https://www.rackaid.com/blog/linux-screen-tutorial-and-how-to/#starting