Comment puis-je désavouer un processus en cours et l'associer à un nouvel écran?

159

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.

L’une des méthodes que j’avais envisagée était de transférer sa propriété sur un écran, pour qu’elle continue de fonctionner.

Y a-t-il une autre façon de procéder?

levesque
la source
8
Voir aussi Est-ce que je peux nohup / screen un processus déjà commencé? et Reprendre la commande en cours d'exécution dans une session SSH abandonnée , qui mentionne plusieurs solutions basées sur ptrace non mentionnées (actuellement) ici.
Gilles
Des questions comme unix.stackexchange.com/a/4039/13496, j’entends parler de retty et neercs . Hmmm ... je me demande s'il y a quelque chose qui ressemble à une couche " écran ici" avant de lancer un processus la prochaine fois que je perdrais le terminal supérieur à l'avenir, cela facilitera le retour dans le stdin / out / err
Marcos
La question secondaire / implicite dans cette question , je ne comprends pas pourquoi est -ce que le ... shell choisir de désavouer un travail suspendu quand il y a une nouvelle / vient de lancer un en arrière - plan qui n'a même pas besoin / attendre stdin? C'est le traitement auquel je me suis habitué alors je ne sais pas ce qui était différent ici ...
Marcos

Réponses:

86

Utiliser GNU screenest votre meilleur choix.

Démarrer l'écran lorsque vous vous connectez pour la première fois - J'exécute screen -D -R, lance votre commande, puis déconnectez-la ou suspendez-la avec CTRL-Z, puis déconnectez-vous de l'écran en appuyant sur CTRL-Apuis sur D.

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

Andrew Yochum
la source
2
Wow, je ne peux pas croire qu'une réponse de GNU Screen est actuellement la moins bien notée. Est-ce que je manque quelque chose?
Faheem Mitha
1
Peut-être! Cela semble être le meilleur pour moi.
Andrew Yochum
1
Rétrospectivement, il semble clairement que ce soit la solution la plus simple, à condition que vous puissiez planifier en conséquence et lancer vos processus à partir d’un environnement d’écran. En tout cas, j'en ai fait la réponse officielle!
Levesque
28
Je pense que cela ne répond pas à la question. La question commence par " J'ai un programme en cours d'exécution ". Cette réponse suppose que ça ne fonctionne pas encore…
Anko
oui il a clairement écrit qu'il voulait le faire dans une session d'écran :-)
Florian Heigl
112

Vous pouvez révoquer la «propriété» du programme à partir du shell avec les éléments disownintégrés suivants:

# press Ctrl+Z to suspend the program
bg
disown

Cependant, cela indique uniquement au shell de ne pas envoyer de SIGHUPsignal au programme lorsque le shell se ferme. Le programme conserve toutes les connexions qu’il a avec le terminal, généralement sous forme de 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, les programmes sont donc attachés à la fenêtre de l'écran.)


Il est possible de rattacher les descripteurs de fichiers à un autre fichier en joignant le programme à un débogueur (c.-à-d. À l'aide de ptrace) et en l'appelant open, dupet close. Il y a quelques outils qui font cela; c'est un processus délicat, et parfois, ils bloquent le processus. 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 effectuer une sélection d'un processus déjà démarré? ):

Gilles
la source
disownsupprime le processus de la liste de contrôle des travaux.
ctrl-alt-delor
3
Pourquoi ne pas disown -h?
Cees Timmerman
@CeesTimmerman Cela laisse le travail dans la table des tâches du shell, mais quel est l'avantage de cela?
Gilles
@Gilles: donc vous pouvez toujours fgou kill, et voir si elle se termine lui - même.
Peter Cordes
Quels utilitaires mentionnés fonctionnent avec un groupe de processus (par exemple bzcat a.bz2 | grep text)? Man for reptyrdit qu'il ne supporte pas le déplacement des processus avec les enfants.
dma_k
64

Vous pouvez utiliser par exemple reptyr pour déplacer un processus entre des terminaux ou pour rattacher un désavoué .

jofel
la source
1
Ouais ça l'a sauvé, merci! J'ai lu le site Web de l'auteur et comment il fonctionne mieux que des outils similaires ou plus anciens, par exemple. pour les programmes ncurses.
Marcos
4
C'est génial; cela devrait résoudre le problème d'un ami qui perd constamment son travail en l'exécutant directement en SSH et en ayant ensuite besoin de monter dans un train. "Oups, j'ai oublié d'utiliser l'écran. Encore."
Adam Katz
3
+1 Bien que la screenréponse acceptée soit bien sûr idéale, elle ne répond pas réellement à la question, qui demande spécifiquement un moyen de déplacer un processus en cours d'exécution screenou similaire. Consultez également cette réponse: serverfault.com/a/284795
toxefa
1
Absolute Live Saver. M'a permis de me reconnecter à l'exécution d'apt dist-upgrade qui attendait la confirmation de l'utilisateur.
andig
28

Ma solution préférée est d'utiliser tmux, vous pouvez détacher la session, et la re-attacher dans un autre terminal.

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

Marguerite
la source
1
vous pouvez également partager votre session avec votre ami et utiliser plusieurs fenêtres et volets et bien plus encore! j'adore ^ _ ^
igor le
exemple d'utilisation s'il vous plaît?
Vitaly Zdanevich
21

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

adamg
la source
19

Je ne l'utilise pas régulièrement, mais neercs prétend le soutenir. Il s’agit d’un screenprogramme avec diverses fonctionnalités sophistiquées comme une meilleure gestion des volets, mais il offre principalement la possibilité d’importer un processus dans un volet.

Michael Mrozek
la source
2
Intéressant. Il joue sale ( ptrace), mais il ne manipule pas simplement les descripteurs de fichier, il lance le processus. Il est capable de saisir find /, mais s'est écrasé une bash interactive.
Gilles
@ Gilles Je ne me souviens pas comment ça s'est passé quand j'ai essayé, mais ça n'a pas une bonne réputation, on me dit que ça échoue assez régulièrement
Michael Mrozek
9

Si vous souhaitez simplement le suspendre et le redémarrer ensuite, vous pouvez utiliser killavec STOPou le CONTsignal.

Découvrez d’abord les processus PID avec

$ ps aux

Puis envoyez les signaux à ce PID indiqué au processus

$ kill -STOP <PID>

$ kill -CONT <PID>
Yunzen
la source
9

"injcode" de ThomasHabets semble être exactement ce 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 à l’avance et que vous exécutiez screen ou tmux.

Du README:

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

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

Commencez par démarrer 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, avec notamment un nouveau terminal de contrôle.

utilisateur2688272
la source
1

Cela a fonctionné pour moi:

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

reptyr« s -Lest nécessaire pour obtenir ce travail:

-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
guaka
la source