web-dev-qa-db-fra.com

Puis-je Nohup / filtrer un processus déjà commencé?

Je fais quelques tests de scripts de migration de données de longue durée, via SSH. Disons que je commence à exécuter un script vers 16 heures; maintenant, 6 PM roule, et je me maudis de ne pas tout faire dans screen.

Existe-t-il un moyen de "rétroactivement" Nohup un processus, ou dois-je laisser mon ordinateur en ligne toute la nuit? S'il n'est pas possible d'attacher screen à/Nohup un processus que j'ai déjà commencé, alors pourquoi? Quelque chose à voir avec la façon dont les processus parents/enfants interagissent? (Je n'accepterai pas une réponse "non" qui ne résout pas au moins la question du "pourquoi" - désolé;))

262
ojrac

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

désavoué

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

Sans options, chaque spécification de tâche est supprimée de la table des tâches actives. Si la -h option 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 SIGHUP. Si jobspec n'est pas présent et que ni le -a ni -r option est fournie, le travail en cours est utilisé. Si aucune spécification de tâche n'est fournie, le -a option signifie supprimer ou marquer tous les travaux; le -r L'option sans argument jobspec limite l'opération aux travaux en cours d'exécution.

212
gharper

Utilisez 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:

82
Jonathan Tran

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 certain reformatage afin de compiler vers les versions Linux/glibc actuelles, mais fonctionne toujours.

22
Juliano

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 tty associé à la session ssh. Nohup fait à peu près juste ...

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

Autrement dit, définit STDIN sur/dev/null, STDOUT sur un fichier et STDERR sur STDOUT. L'écran fait des choses beaucoup plus sophistiquées impliquant la configuration de ttys qui se dirigent vers lui-même.

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

Vous pourriez avoir de la chance avec le reniement, mais pas si le processus essaie de faire quoi que ce soit avec STDIN, STDOUT ou STDERR.

17
freiheit

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

Cependant, avez-vous essayé disown (un module intégré bash)

~ $ 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.
13
serverhorror

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.

13
TRS-80

Nohup sur Solaris/OpenSolaris a un indicateur -p pour Nohup un processus en cours d'exécution - par exemple, consultez la page de manuel Solaris 10 Nohup .

9
alanc

J'ai récemment vu un lien vers neercs , qui est un utilitaire de type écran construit à l'aide de libcaca, une bibliothèque de couleurs ascii-art. Entre autres fonctionnalités, il offre la possibilité de récupérer un processus existant et de le re-parent dans votre session neercs (écran).

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

5
Daniel Lawson

Vous pouvez rediriger la sortie du processus vers un fichier avec gdb

https://blog-en.openalfa.com/how-to-detach-from-the-terminal-a-running-process-in-linux

puis le renier

Upd: J'ai dû exécuter gdb avec Sudo et une commande gdb légèrement différente dans Ubuntu 18.04:

p (int)dup2(open("/tmp/test.stdout", 1), 1)

2
d9k

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

2
Chris_K

Si vous pouvez vivre sans pouvoir interagir 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. Ici est un appel injcode, qui peut principalement faire ce que vous voulez faire.

2
David Pashley

Je voulais utiliser Nohup (ou similaire) pour démarrer le navigateur de ligne de commande links et le joindre après pour télécharger un fichier à partir du site Web ASP.NET avec un processus d'authentification compliqué et beaucoup de état de la vue cachée qui rendait difficile l'utilisation du travail avec curl/wget.

J'ai finalement fini par utiliser tmux qui a résolu le problème:

  1. Exécutez tmux
  2. Exécutez votre application (links dans mon cas) et laissez-la fonctionner
  3. Fermer la session SSH, l'application continuera de fonctionner
  4. Connectez-vous avec SSH à la même machine ultérieurement et exécutez tmux attach pour ramener l'application à l'écran
1
Dmitry Gusev