Je me connecte à une machine Linux via SSH et j'essaie d'exécuter un script bash lourd qui effectue des opérations sur le système de fichiers. Il devrait continuer à fonctionner pendant des heures, mais je ne peux pas laisser la session SSH ouverte en raison de problèmes de connexion Internet.
Je doute que l'exécution du script avec l'opérateur d'arrière-plan, l'esperluette (&
), fera l'affaire, car je l'ai essayé et j'ai constaté plus tard que le processus n'était pas terminé. Comment puis-je me déconnecter et poursuivre le processus?
La meilleure méthode consiste à démarrer le processus dans un multiplexeur terminal. Vous pouvez également empêcher le processus de recevoir le signal HUP.
Un terminal multiplexeur fournit des terminaux "virtuels" qui fonctionnent indépendamment du "vrai" terminal (en fait tous les terminaux sont aujourd'hui "virtuels" mais c'est un autre sujet pour un autre jour). Le terminal virtuel continuera de fonctionner même si votre véritable terminal est fermé avec votre session ssh.
Tous les processus démarrés à partir du terminal virtuel continueront de fonctionner avec ce terminal virtuel. Lorsque vous vous reconnectez au serveur, vous pouvez vous reconnecter au terminal virtuel et tout se passera comme si de rien n'était, autre que le temps qui s'est écoulé.
Deux multiplexeurs de terminaux populaires sont écran et tmux .
L'écran a une courbe d'apprentissage abrupte. Voici un bon tutoriel avec des diagrammes expliquant le concept: http://www.ibm.com/developerworks/aix/library/au-gnu_screen/
Le signal HUP (ou SIGHUP) est envoyé par le terminal à tous ses processus enfants lorsque le terminal est fermé. L'action commune à la réception de SIGHUP est de mettre fin. Ainsi, lorsque votre session ssh sera déconnectée, tous vos processus se termineront. Pour éviter cela, vous pouvez faire en sorte que vos processus ne reçoivent pas SIGHUP.
Deux méthodes simples pour le faire sont Nohup
et disown
.
Pour plus d'informations sur le fonctionnement de Nohup
et disown
, lisez cette question et sa réponse: https://unix.stackexchange.com/questions/3886/difference-between-Nohup-disown -et
Remarque: bien que les processus continuent de fonctionner, vous ne pouvez plus interagir avec eux car ils ne sont plus attachés à aucun terminal. Cette méthode est principalement utile pour les processus par lots de longue durée qui, une fois démarrés, ne nécessitent plus aucune entrée utilisateur.
Il existe plusieurs façons de le faire, mais celle que je trouve la plus utile consiste à utiliser écran GN .
Après avoir introduit ssh, exécutez screen
. Cela démarrera un autre Shell exécuté dans l'écran. Exécutez votre commande, puis effectuez une Ctrl-ad.
Cela vous "déconnectera" de la session écran. À ce stade, vous pouvez vous déconnecter ou faire tout ce que vous souhaitez.
Lorsque vous souhaitez vous reconnecter à la session écran, exécutez simplement screen -RD
à partir de l'invite du shell (en tant que même utilisateur qui a créé la session).
Dans bash
, le mot clé disown
est parfaitement adapté à cela. Tout d'abord, exécutez votre processus en arrière-plan (utilisez soit &
, ou ^Z
puis tapez bg
):
$ wget --quiet http://server/some_big_file.Zip &
[1] 1156
En tapant jobs
, vous pouvez voir que le processus appartient toujours au shell:
$ jobs
[1]+ Running wget
Si vous deviez vous déconnecter à ce stade, la tâche d'arrière-plan serait également tuée. Cependant, si vous exécutez disown
, bash détache le travail et lui permet de continuer à s'exécuter:
$ disown
Vous pouvez le confirmer:
$ jobs
$ logout
Vous pouvez même combiner le &
et disown
sur la même ligne, comme:
$ wget --quiet http://server/some_big_file.Zip & disown
$ logout
C'est mieux que d'exécuter Nohup
à mon avis car cela ne laisse pas Nohup.out
fichiers jonchent tout le système de fichiers. De plus, Nohup
doit être exécuté avant d'exécuter la commande - disown
peut être utilisé si vous décidez plus tard que vous souhaitez créer un arrière-plan et détacher la tâche.
L'outil Nohup, disponible sur la plupart des boîtiers Linux, le fera.
Juste pour être minutieux, je soulignerai tmux , qui a la même idée de base que screen:
tmux est destiné à être une alternative moderne, sous licence BSD, à des programmes tels que l'écran GNU. Les principales fonctionnalités incluent:
- Une interface de commande puissante, cohérente, bien documentée et facilement scriptable.
- Une fenêtre peut être divisée horizontalement et verticalement en volets.
- Les volets peuvent être librement déplacés et redimensionnés, ou disposés en dispositions prédéfinies.
- Prise en charge des terminaux UTF-8 et 256 couleurs.
- Copiez et collez avec plusieurs tampons.
- Menus interactifs pour sélectionner des fenêtres, des sessions ou des clients.
- Modifiez la fenêtre actuelle en recherchant du texte dans la cible.
- Verrouillage du terminal, manuellement ou après une temporisation.
- Une base de code propre, facilement étendue et sous licence BSD, en cours de développement actif.
Il est cependant environ infiniment plus facile à rechercher sur Google.
L'écran est exagéré pour simplement maintenir les processus en cours lorsque vous vous déconnectez.
Essayez dtach :
dtach est un programme écrit en C qui émule la fonction de détachement de screen, qui permet à un programme d'être exécuté dans un environnement protégé du terminal de contrôle. Par exemple, le programme sous le contrôle de dtach ne serait pas affecté par la déconnexion du terminal pour une raison quelconque.
dtach a été écrit parce que screen ne répondait pas adéquatement à mes besoins; Je n'avais pas besoin des fonctionnalités supplémentaires de l'écran, telles que la prise en charge de plusieurs terminaux ou la prise en charge de l'émulation de terminal. l'écran était également trop grand, encombrant et avait un code source difficile à comprendre.
screen a également interféré avec mon utilisation d'applications plein écran telles que emacs et ircII, en raison de son interprétation excessive du flux entre le programme et les terminaux connectés. dtach n'a pas de couche d'émulation de terminal et transmet le flux de sortie brut du programme aux terminaux connectés. Le seul traitement d'entrée effectué par dtach est la recherche du caractère de détachement (qui signale à dtach de se détacher du programme) et le traitement de la clé de suspension (qui indique à dtach de se suspendre temporairement sans affecter le programme en cours), et les deux peuvent tous les deux être désactivé si vous le souhaitez.
Contrairement à l'écran, dtach a des fonctionnalités minimales et est extrêmement petit. Cela permet à dtach d'être plus facilement audité pour les bogues et les failles de sécurité, et le rend accessible dans les environnements où l'espace est limité, comme sur les disques de secours.
Voici un moyen de démoniser n'importe quel processus Shell, aucun programme externe requis:
( while sleep 5; do date; done ) <&- >output.txt &
Lorsque vous fermez ensuite votre session, le travail continue de s'exécuter comme en témoigne le fichier output.txt (qui a une mise en mémoire tampon, il faut donc un certain temps pour afficher une valeur non nulle). N'oubliez pas de tuer votre travail après le test.
Il vous suffit donc de fermer stdin et d'arrière-plan du travail. Pour être vraiment bon, d'abord cd /
pour ne pas vous accrocher à une monture.
Cela fonctionne même en simple sh sous Solaris.
La commande at
peut être utile pour ce type de situation. Par exemple, tapez:
at now
Et vous pouvez ensuite entrer une commande ou une série de commandes qui seront exécutées. Les résultats doivent vous être envoyés par e-mail si l'e-mail est correctement configuré sur la machine.
Au lieu de now
, vous pouvez spécifier une heure avec une date ou une expression d'heure comme now + 15 minutes
. Voir man at
pour plus de détails.
byobu
sur Ubuntu est un joli front-end à l'écran. En appuyant Ctrl-? vous obtenez une liste de tous les raccourcis clavier. Il ajoute une barre d'état qui peut être utile pour surveiller la charge du processeur, l'espace disque, etc. Globalement, il fournit une expérience que je décrirais comme une connexion VNC basée sur un terminal.
Nohup
permet de démarrer un travail en arrière-plan avec sa sortie routée vers un fichier journal, qui peut toujours être redirigé vers/dev/null si cela n'est pas nécessaire.