web-dev-qa-db-fra.com

Comment désavouer un processus en cours et l'associer à un nouveau shell d'écran?

J'ai un programme en cours d'exécution sur un shell SSH. Je veux le suspendre et pouvoir suspendre son exécution à mon retour.

Une façon d'y penser était de transférer sa propriété sur un écran Shell, le faisant ainsi fonctionner.

Y a-t-il une manière différente de procéder?

164
levesque

Utiliser GNU screen est votre meilleur choix.

L'écran de démarrage s'exécute lors de votre première connexion - J'exécute screen -D -R, exécutez votre commande et déconnectez-la ou suspendez-la avec CTRL-Z puis vous déconnecter de l'écran en appuyant sur CTRL-A puis D.

Lorsque vous vous reconnectez à la machine, reconnectez-vous en exécutant screen -D -R. Vous serez dans le même Shell qu'avant. Vous pouvez exécuter jobs pour voir le processus suspendu si vous l'avez fait, et exécuter %1 (ou le numéro de travail respectif) pour le mettre de nouveau en avant-plan.

88
Andrew Yochum

Vous pouvez révoquer la "propriété" du programme à partir du shell avec le disown intégré:

# press Ctrl+Z to suspend the program
bg
disown

Cependant, cela indique uniquement au shell de ne pas envoyer de signal SIGHUP au programme lorsque le shell se ferme. Le programme conservera toute connexion qu'il a avec le terminal, généralement en tant que flux d'entrée, de sortie et d'erreur standard. Il n'y a aucun moyen de les rattacher à un autre terminal. ( Screen fonctionne en émulant un terminal pour chaque fenêtre, donc les programmes sont attachés à la fenêtre d'écran.)


Il est possible de rattacher les descripteurs de fichier à un fichier différent en attachant le programme dans un débogueur (c'est-à-dire en utilisant ptrace ) et en le faisant appeler open, dup et close. Il existe quelques outils pour ce faire; il s'agit d'un processus délicat, et parfois, ils bloquent le processus à la place. Les possibilités incluent (liens collectés à partir des réponses à Comment puis-je désavouer un processus en cours et l'associer à un nouveau shell d'écran? et Puis-je Nohup/filtrer un processus déjà commencé? =):

Pour déplacer un processus entre des terminaux ou rattacher un désavoué, vous pouvez utiliser par exemple reptyr .

67
jofel

Ma solution préférée utilise tmux, vous pouvez détacher la session et la rattacher à un autre terminal.

Lorsque vous vous êtes détaché de la session précédente, vous pouvez fermer le terminal en toute sécurité; utiliser ultérieurement tmux attach pour revenir à la session, même si vous vous êtes déconnecté.

28
daisy

Il existe également un petit utilitaire appelé retty qui vous permet de rattacher des programmes en cours d'exécution à un autre terminal.

21
adamg

Je ne l'utilise pas régulièrement, mais neercs prétend le supporter. C'est un programme semblable à screen avec diverses fonctionnalités sophistiquées comme une meilleure gestion des volets, mais la principale chose qu'il offre est la possibilité d'importer un processus dans un volet

19
Michael Mrozek

Si vous voulez simplement le suspendre et redémarrer ensuite, vous pouvez utiliser kill avec le signal STOP ou CONT.

Découvrez dans un premier temps les processus PID avec

$ ps aux

Envoyez ensuite les signaux à ce PID répertorié dans le processus

$ kill -STOP <PID>

$ kill -CONT <PID>
9
yunzen

"injcode" de ThomasHabets semble être exactement la chose dont j'ai besoin:

https://github.com/ThomasHabets/injcode

Le programme injcode permet d'injecter du code arbitraire dans un processus en cours, que vous le sachiez ou non et que vous exécutiez screen ou tmux

Du README:

Exemple 1: déplacer l'irssi d'un terminal à un autre

Peut-être le déplacer dans un écran.

Démarrez d'abord irssi dans un terminal.

Exécutez injcode dans un autre terminal: $ injcode -m retty

Irssi devrait maintenant être déplacé vers le deuxième terminal, y compris avoir un nouveau terminal de contrôle.

9
user2688272

Cela a fonctionné pour moi:

  1. bg le processus
  2. jobs -l rechercher le numéro de processus
  3. tmux démarrer le gestionnaire de fenêtres Shell
  4. reptyr -L PROCESSNUMBER

reptyr's -L était nécessaire pour que cela fonctionne:

-L Like '-l', but also redirect the child's stdio to the slave.

à cause de cette erreur:

$ reptyr 30622

[-] Unable to open the tty in the child.
Unable to attach to pid 30622: Permission denied

Et avec -L

$ reptyr -L 30622
Opened a new pty: /dev/pts/4
1
kqw