Est-ce que je peux nohup / screen un processus déjà commencé?

260

Je fais des essais de scripts de migration de données à exécution longue, sur SSH. Disons que je commence à exécuter un script vers 16 heures; À présent, 18 heures sont là et je me maudis de ne pas avoir fait tout ça screen.

Existe-t-il un moyen de nohupprocéder "de manière rétroactive" à un processus ou dois-je laisser mon ordinateur en ligne toute la nuit? S'il est impossible d'attacher screenà / nohupun processus que je l' ai déjà commencé, alors pourquoi? Quelque chose à voir avec la façon dont les processus parent / enfant interagissent? (Je n'accepterai pas une réponse "non" qui ne répond pas au moins à la question "pourquoi" - désolé;))

ojrac
la source
4
Je viens de voir un article de blog intéressant sur disown. blogs.oracle.com/ksplice/entry/disown_zombie_children_and_the
ojrac

Réponses:

212

Si vous utilisez Bash, vous pouvez exécuter disown -h job

renier

disown [-ar] [-h] [jobspec ...]

Sans options, chaque tâche spécifiée est supprimée du tableau des tâches actives. Si l' -hoption est donnée, le travail n'est pas supprimé de la table, mais est marqué de sorte que SIGHUP ne soit pas envoyé au travail si le shell reçoit un message SIGHUP. Si jobpec n’est pas présent et que ni l’ option -ani -rn’est fournie, le travail en cours est utilisé. Si aucun jobpec n’est fourni, l’ -a option signifie supprimer ou marquer tous les jobs; l' -roption sans l'argument jobspec limite l'opération à l'exécution des travaux.

gharper
la source
Impressionnant; J'espérais que quelque chose comme cela se présenterait.
Ojrac
7
La vie peut être injuste. Gharper et moi publions cela à peu près au même moment :)
serverhorror Le
4
Vous êtes mon héros
Thomas Dignan le
9
désavouer n'est pas spécifique à bash. C'est aussi en zsh, ksh93, ...
Phil P
2
J'ai trouvé que vous devez réellement utiliser disown %1si 1 est le jobpec, contrairement à fg ou bg où vous utilisez simplement bg 1 serverwatch.com/tutorials/article.php/3935306/…
mltsy le
81

Utilisez le reptyr

Du README:

reptyr - A tool for "re-ptying" programs.
-----------------------------------------

reptyr is a utility for taking an existing running program and
attaching it to a new terminal. Started a long-running process over
ssh, but have to leave and don't want to interrupt it? Just start a
screen, use reptyr to grab it, and then kill the ssh session and head
on home.

USAGE
-----

  reptyr PID

"reptyr PID" will grab the process with id PID and attach it to your
current terminal.

After attaching, the process will take input from and write output to
the new terminal, including ^C and ^Z. (Unfortunately, if you
background it, you will still have to run "bg" or "fg" in the old
terminal. This is likely impossible to fix in a reasonable way without
patching your shell.)

Quelques articles de blog de son auteur:

Jonathan Tran
la source
Je vais m'en tenir aux outils intégrés (c.-à-d. Désavouer), mais ce n'est pas aussi flexible que reptyr. +1
octobre
22

Pour voler un processus d'un tty à votre tty actuel, vous pouvez essayer ce hack:

http://www.ucc.asn.au/~dagobah/things/grab.c

Il a besoin d’un peu de reformatage pour pouvoir compiler les versions actuelles de Linux / glibc, mais fonctionne toujours.

Juliano
la source
1
Exceptionnellement cool.
Ojrac
16

Lorsqu'un processus démarre, STDIN, STDOUT et STDERR sont connectés à quelque chose . Généralement, vous ne pouvez pas changer cela une fois la commande lancée. Dans le cas que vous décrivez, c'est probablement un terminal associé à la session SSH. nohup à peu près tout simplement ...

command < /dev/null > nohup.out 2>&1

En d’autres termes, définit STDIN sur / dev / null, STDOUT sur un fichier et STDERR sur STDOUT. Screen fait des choses beaucoup plus sophistiquées impliquant la mise en place de ttys qui se dirigent vers lui-même.

Je ne connais aucun moyen de supprimer rétroactivement ou de filtrer un processus en cours. Si vous cd dans / proc / $ pid / fd et voyez ce que 0, 1 et 2 désignent.

Vous pouvez avoir de la chance avec désavoué, mais pas si le processus tente de faire quoi que ce soit avec STDIN, STDOUT ou STDERR.

freiheit
la source
2
+1 pour les bons commentaires. st (din | out | err) est l’autre moitié du problème, et j’apprécie le conseil de départ, la prochaine fois que je serai dans cette impasse.
Ojrac
6
Vous pouvez réellement le changer sur la plupart des Unix. C'est un hack dégoûtant. J'aime cela. :) Ce que vous faites est de vous connecter au processus en utilisant le support de débogage comme ptrace, puis de forcer le processus à appeler dup2 () pour reconnecter 0,1,2 à un autre descripteur de fichier.
Zan Lynx
2
oui, vous pouvez le changer. Implique de suspendre le processus (SIGSTOP) et de modifier les descripteurs de fichier pour fd 0, 1, 2. Ensuite, redémarrage (SIGCONT).
Michael Martinez
13

Cryopid est un développement ultérieur de l'auteur de grab.c qui fige un processus dans un fichier que vous exécutez ensuite (à l'intérieur de l'écran) pour reprendre le processus.

TRS-80
la source
1
Agréable! J'ai essayé d'utiliser cryopid dans la thèse de mon maître sur la migration de processus, mais cela ne fonctionnait pas tout le temps, peu importe ce que je faisais. Finalement, j'ai dû utiliser dynckpt avec une version ancienne de Linux. Êtes-vous peut-être impliqué dans le développement de cryopid? Je vois que votre nom est similaire au domaine de l'auteur.
Juliano
1
Je ne suis pas impliqué dans le développement, je connais juste l'auteur de l'université. Il n'a pas le temps de maintenir cryopid pour le moment, alors il semblerait que certaines personnes aient
TRS-80
12

Je ne peux que vous donner un simple "Non" sans le pourquoi pour la partie écran, je serais intéressé par la raison moi-même.

Cependant avez-vous essayé disown(une bash intégrée)

~ $ echo $SHELL
/bin/bash
~ $ type disown
disown is a shell builtin
~ $ 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.
serveurhorror
la source
5

J'ai récemment vu un lien vers neercs , un utilitaire semblable à un écran, construit à l'aide de libcaca, une bibliothèque de couleurs ascii-art. Parmi d'autres fonctionnalités, il offre la possibilité de capturer un processus existant et de le re-parent au sein de votre session (écran) suivante.

Je ne l'ai pas utilisé cependant, donc je ne peux pas dire si cela fonctionne ou non.

Daniel Lawson
la source
2

Je suis probablement en train de penser cela, alors n'hésitez pas à me corriger (j'ai déjà appris le désaveu!) ... Un ctrl-Z et un "bg" ne fonctionneraient-ils pas au moins pour que le processus s'exécute en arrière-plan? Ou bien est-ce le problème clé pour lequel vous souhaitez toujours voir STDOUT pendant son exécution?

Chris_K
la source
1
Cela tuerait toujours le processus lorsque le propriétaire possédant serait mort, de sorte que l'OP doit quitter la boîte où il a lancé la commande en cours d'exécution, ce qu'il veut éviter
serverhorror
OK je vais acheter ça. Merci pour l'explication. Donc, les suggestions de désaveu -h ont l'air beaucoup plus intelligentes que les miennes :-)
Chris_K
1
Vous pouvez toujours le faire, juste après avoir désavoué -h: stackoverflow.com/a/625436/705198
AndrewPK le
2

Si vous ne pouvez pas vivre avec le processus et que vous ne vous opposez pas au chargement de modules de noyau aléatoires, vous pourriez faire pire que de regarder Snoop . Alternativement, il y a quelques autres projets. Voici un appel injcode, qui peut principalement faire ce que vous voulez faire.

David Pashley
la source
1

Je voulais utiliser nohup(ou similaire) pour démarrer le linksnavigateur de ligne de commande et y attacher ensuite pour télécharger un fichier à partir du site Web ASP.NET avec un processus d'authentification complexe et de nombreux états d'affichage masqués qui rendaient l'utilisation du travail difficile. avec curl/ wget.

J'ai finalement fini par utiliser tmuxce qui a résolu le travail tout simplement génial:

  1. Courir tmux
  2. Exécutez votre application ( linksdans mon cas) et laissez-la en cours d'exécution
  3. Fermer la session SSH, l'application restera en cours d'exécution
  4. Connectez-vous avec SSH au même ordinateur plus tard et exécutez-le tmux attachpour ramener l'application à l'écran.
Dmitry Gusev
la source
tmux est génial - mais, comme nohup ou screen, cela ne fonctionne que si vous l'utilisez avant de commencer votre processus. Cette question concerne les moments où vous réalisez que vous avez besoin de tmux après que votre processus est déjà en cours d'exécution.
Ojrac
-1

Est-ce que tu t'inquiètes de la fin de la session? Dans ce cas, vous pouvez Ctrl-z et bg le processus, puis il suffit de mettre quelque chose pour maintenir la session active comme un "ping -t localhost" ou "top".

Si c'est ce que vous voulez vous déconnecter, alors je crains de ne pas pouvoir ajouter d'autres commentaires.

Nom de Troie
la source
C'est la chose la déconnexion.
Ojrac
1
Une autre façon d'empêcher la déconnexion est de courir en haut. C'est toujours en train de mélanger quelques octets.
Rory