Une fois connecté ssh
, je tape cette commande dans bash
:
sleep 50000000000000 &
Ensuite, je kill -9
le sleep
processus parent du processus (c.-à bash
-d.). Ensuite, la fenêtre du terminal se déconnecte simultanément.
Lorsque je me reconnecte, je constate que le sleep
processus est toujours en cours.
Question : Pourquoi le sleep
processus peut-il survivre lorsque je me déconnecte et que le terminal est fermé? Dans mon esprit, tout sauf les démons et les nohup
programmes sera tué lors de la déconnexion. Si sleep
peut survivre de cette façon, cela signifie-t-il que je peux utiliser cette méthode à la place de la nohup
commande?
&
va bifurquer le processus en arrière-plan (comme le démon) et continue de fonctionner même si vous êtes déconnecté.Réponses:
Tl; dr:
À moins que l'
bash
instance engendrée parssh
n'ait l'huponexit
option définie, aucun processus ne sera interrompu de quelque manière que ce soit à la sortie / déconnexion, et lorsque l'huponexit
option est définie, l'utilisationkill -9
sur le shell n'est pas une bonne alternative à l'utilisationnohup
sur les processus enfants du shell;nohup
sur le shell, les processus enfants les protégeront toujours contre les SIGHUP qui ne proviennent pas du shell, et même lorsque cela n'est pas important, ilnohup
faut toujours le préférer car cela permet de terminer le shell avec élégance.Il
bash
y a une option appeléehuponexit
qui, si elle est définie, fera debash
SIGHUP ses enfants à la sortie / déconnexion;Dans les
bash
instances interactives sans connexion , comme dans unebash
instance générée pargnome-terminal
, cette option est ignorée; qu'ilhuponexit
soit réglé ou non,bash
les enfants de 'S ne seront jamais SIGHUPpésbash
à la sortie;Dans les instances de connexion interactive
bash
, comme dans unebash
instance engendrée parssh
, cette option n'est pas ignorée (mais elle n'est pas définie par défaut); s'ilhuponexit
est défini,bash
les enfants de SIGHUP seront suivis parbash
à la sortie / déconnexion; s'ilhuponexit
n'estbash
pas défini , les enfants de ne seront pas SIGHUPpedbash
à la sortie / déconnexion;Donc, en général, la fermeture / déconnexion d'une
bash
instance de connexion interactive , sauf si l'huponexit
option est définie, ne fera pas du shell SIGHUP ses enfants, et la fermeture / déconnexion d'unebash
instance interactive sans connexion ne fera pas du shell SIGHUP ses enfants indépendamment;Cela n'est cependant pas pertinent dans ce cas: l'utilisation
kill -9
sleep
survivra malgré tout, car la suppression de son processus parent (bash
) ne laissera aucune chance à ce dernier de faire quoi que ce soit à l'ancien (par exemple, si l'bash
instance actuelle était unebash
instance de connexion) . et l'huponexit
option a été définie, à SIGHUP it).De plus, contrairement à d'autres signaux (comme un signal SIGHUP envoyé à
bash
), un signal SIGKILL n'est jamais propagé aux processus enfants d'un processus, ilsleep
n'est donc même pas tué;nohup
démarre un processus insensible aux signaux SIGHUP, ce qui est différent; cela empêchera le processus de raccrocher à la réception d'un signal SIGHUP, qui dans ce cas pourrait être reçu par l'bash
instance de connexion interactive au cas où l'huponexit
option aurait été définie et le shell quitté; donc, techniquement, utilisernohup
pour démarrer un processus dans unebash
instance de connexion interactive avec l'huponexit
option unset empêchera le processus de raccrocher à la réception d'un signal SIGHUP, mais quitter / se déconnecter du shell ne le SIGHUP le fera pas indépendamment;En général, cependant, lorsque cela
nohup
est nécessaire pour empêcher les signaux SIGHUP provenant du shell parent, il n'y a aucune raison de préférer lakill -9
méthode on the parent à la méthodenohup
on the child; au contraire, ce devrait être le contraire.Tuer le parent à l'aide de la
kill -9
méthode ne laisse aucune chance au parent de sortir avec élégance, tandis que le démarrage de l'enfant à l'aide de lanohup
méthode permet au parent d'être interrompu par d'autres signaux, tels que SIGHUP (pour donner un exemple qui a du sens dans le contexte d'un enfant a commencé à utilisernohup
), ce qui lui permet de sortir avec élégance.la source
ps -e | grep process
lister les processus avec le PID (ou mieux justepgrep -x process
si vous êtes sûr de faire correspondre ce seul processus et non des choses non désirées); le problème est que lorsque vous tuez un processus aveckill -9
ses enfantsupstart
, leur PPID d'origine est perdu et leur PPID change en PID parvenu, les rendant méconnaissables (AFAIK) mais pour leur nom ou PIDnohup
n'empêchera-t-il pas un processus de raccrocher lors de la réception d'un signal SIGHUP du processus parent? J'essaie d'exécuter un processus en arrière-plan (dans un terminal shell PuTTY SSH) parnohup <command> <arg> &
. Lorsque je me déconnecte en cliquant sur leX
bouton PuTTY , le processus d'arrière-plan se termine immédiatement. Lorsque je me déconnecte en tapantexit
dans le terminal shell PuTTY SSH, le processus continue de s'exécuter en arrière-plan.bash
par défaut n'envoie pas le signal HUP aux processus enfants lors de la fermeture . Plus en détail (merci @kos), il ne le fait jamais pour les shells sans connexion .Vous pouvez configurer bash pour le faire pour les shells de connexion si vous définissez l'option
huponexit
. Dans un terminal, faites:(ceci lance un nouveau shell "login")
Maintenant, vérifiez le
sleep
processus:... ne fonctionne pas: il a reçu le signal HUP et est sorti comme demandé.
la source
sleep 1000 & ; exit
lessleep
survive? Notez que si jekill -HUP
lesleep
processus, il se terminera . Et même s'il esthuponexit
réglé, lesleep
survit. Confus ... (je vais essayer de mieux comprendre et de modifier la réponse, sinon je vais le supprimer).kill -9
ce n'est vraiment pas la voie à suivre. C'est comme tirer avec un pistolet sur le téléviseur pour l'éteindre. Outre la composante comique, il n'y a aucun avantage. Les processus ne peuvent pas attraper ou ignorerSIGKILL
. Si vous ne donnez pas au processus une chance de terminer ce qu'il fait et de nettoyer, il peut laisser des fichiers corrompus (ou un autre état) et ne pourra pas redémarrer.kill -9
est le dernier espoir, quand rien d'autre ne fonctionne.Que se passe-t-il dans votre cas:
Le processus parent de
sleep
est lebash
shell en cours d'exécution . Lorsque vouskill -9
bash, le processus bash n'a pas la possibilité d'envoyer unSIGHUP
à l'un de ses processus enfants, carSIGKILL
(qui est envoyé parkill -9
) n'est pas capturable par le processus. Le processus de mise en veille continue de s'exécuter. le sommeil est devenu un processus orphelin .Le processus init (PID 1) fait un mécanisme appelé reparenting. Cela signifie que le processus init devient maintenant le parent de ce processus orphelin. init est une exception, les processus peuvent devenir son enfant car il collecte les processus qui ont perdu leur processus parent d'origine. Btw: Un démon (comme
sshd
) fait cela lorsqu'il "va en arrière-plan".Si cela ne se produisait pas, le processus orphelin deviendrait plus tard (une fois terminé) un processus zombie. C'est ce qui se produit quand
waitpid()
n'est pas appelé (une responsabilité du processus parent qui ne peut pas être remplie lorsque ce processus a été tué). init appellewaitpid()
dans un intervalle spécifique pour éviter les enfants zombies.la source
TERM
ouHUP
huponext
. Et TERM attendra la fin du sommeil. Dans le cas de la commande OPs sleep, ce serait des milliers d'années =)Le
&
démarre le processus en arrière-plan. Si vous tapezps -ef
, vous verrez que l'ID de processus parent (PPID) de votre sommeil est votre bash. Déconnectez-vous ensuite et reconnectez-vous. Le processus continuera de fonctionner après votre déconnexion. Après vous être connecté pour la deuxième fois, vous exécutez àps -ef
nouveau. Vous verrez que maintenant le parent de votre processus de sommeil sera traité avec l'identifiant "1". C'est init, le parent de tous les processus.la source
L'utilisation
&
entraînera l'exécution du programme en arrière-plan. Pour voir le programme dans labg
commande d' arrière-plan et le faire à nouveau fonctionner comme premier plan, exécutezfg
.Oui, il existe de nombreuses façons de continuer à exécuter le programme même après la sortie du terminal principal.
la source
huponexit
ne fonctionne que sur les shells de connexion tels qu'un shell obtenu viassh
(et non, disons, dans un shell obtenu viagnome-terminal
)