Question Comment mettre un processus déjà en cours sous nohup?


J'ai un processus qui est déjà en cours depuis longtemps et je ne veux pas le terminer.

Comment puis-je le mettre sous nohup (c'est-à-dire, comment puis-je le faire continuer à fonctionner même si je ferme le terminal?)


775
2018-03-09 08:33


origine


Réponses:


En utilisant le Contrôle du travail de bash pour envoyer le processus en arrière-plan:

  1. Ctrl+Z pour arrêter (pause) le programme et revenir à la coquille.
  2. bg pour l'exécuter en arrière-plan.
  3. disown -h [job-spec] où [job-spec] est le numéro de l'emploi (comme %1 pour le premier travail en cours; trouver à propos de votre numéro avec le jobs commande) afin que le travail ne soit pas tué lorsque le terminal se ferme.

1153
2018-03-09 08:41



Supposons pour une raison quelconque Ctrl+Z ne fonctionne pas, aller à un autre terminal, trouver l'identifiant du processus (en utilisant ps) et courir:

kill -20 PID 
kill -18 PID

kill -20 (SIGTSTP) suspendra le processus et kill -18 (SIGCONT) va reprendre le processus, en arrière-plan. Alors maintenant, la fermeture de vos deux terminaux n'arrêtera pas votre processus.


141
2018-04-23 08:01



La commande pour séparer un travail en cours du shell (= le fait nohup) est disown et une commande shell de base.

De bash-manpage (homme bash):

désavouer [-ar] [-h] [jobpec ...]

Sans options, chaque jobpec est supprimé de la table des tâches actives. Si l'option -h est donnée, chaque jobpec n'est pas   supprimé de la table, mais marqué de sorte que SIGHUP ne soit pas envoyé au travail si le shell reçoit un SIGHUP. Si aucun jobpec n'est   présent, et ni l'option -a ni l'option -r n'est fournie, le travail en cours est utilisé. Si aucun jobpec n'est fourni, l'option -a   des moyens pour supprimer ou marquer tous les travaux; l'option -r sans argument jobspec limite l'opération aux tâches en cours d'exécution. Le retour   La valeur est 0 sauf si un jobpec ne spécifie pas un travail valide.

Cela signifie qu'un simple

disown -a

va supprimer tous les emplois de la table de travail et les rend nohup


72
2018-03-09 08:38



Ce sont de bonnes réponses ci-dessus, je voulais juste ajouter une précision:

Tu ne peux pas disown un pid ou un processus, vous disown un travail, et c'est une distinction importante.

Un travail est quelque chose qui est une notion d'un processus attaché à un shell, par conséquent vous devez mettre le travail en arrière-plan (pas le suspendre) et le renier ensuite.

Problème:

%  jobs
[1]  running java 
[2]  suspended vi
%  disown %1

Voir http://www.quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/jobcontrol/ pour une discussion plus détaillée de Unix Job Control.


60
2017-11-19 15:48



Malheureusement disown est spécifique à bash et non disponible dans toutes les coques.

Certaines versions d'Unix (par exemple AIX et Solaris) ont une option sur nohup commande elle-même qui peut être appliquée à un processus en cours d'exécution:

nohup -p pid

Voir http://en.wikipedia.org/wiki/Nohup


36
2018-03-16 23:49



La réponse de Node est vraiment géniale, mais elle laisse ouverte la question de savoir comment obtenir stdout et stderr redirigés. J'ai trouvé une solution sur Unix et Linuxmais ce n'est pas complet non plus. Je voudrais fusionner ces deux solutions. C'est ici:

Pour mon test j'ai fait un petit script bash appelé loop.sh, qui imprime le pid de lui-même avec une minute de sommeil dans une boucle infinie.

$./loop.sh

Maintenant, obtenez le PID de ce processus en quelque sorte. habituellement ps -C loop.sh est assez bon, mais il est imprimé dans mon cas.

Maintenant nous pouvons passer à un autre terminal (ou appuyer sur ^ Z et dans le même terminal). À présent gdb devrait être attaché à ce processus.

$ gdb -p <PID>

Cela arrête le script (s'il est en cours d'exécution). Son état peut être vérifié par ps -f <PID>, où le STAT le champ est 'T +' (ou dans le cas de ^ Z 'T'), ce qui signifie (man ps (1))

    T Stopped, either by a job control signal or because it is being traced
    + is in the foreground process group

(gdb) call close(1)
$1 = 0

Close (1) renvoie zéro en cas de succès.

(gdb) call open("loop.out", 01102, 0600)
$6 = 1

Open (1) renvoie le nouveau descripteur de fichier en cas de succès.

Cette ouverture est égale à open(path, O_TRUNC|O_CREAT|O_RDWR, S_IRUSR|S_IWUSR). Au lieu de O_RDWR  O_WRONLY pourrait être appliqué, mais /usr/sbin/lsof dit 'u' pour tous les gestionnaires de fichiers std * (FD colonne), qui est O_RDWR.

J'ai vérifié les valeurs dans le fichier d'en-tête /usr/include/bits/fcntl.h.

Le fichier de sortie pourrait être ouvert avec O_APPEND, comme nohup ferait, mais ce n'est pas suggéré par man open(2), en raison de problèmes NFS possibles.

Si nous obtenons -1 comme valeur de retour, alors call perror("") imprime le message d'erreur. Si nous avons besoin de l'errno, utilisez p errno gdb comand.

Maintenant, nous pouvons vérifier le fichier nouvellement redirigé. /usr/sbin/lsof -p <PID> impressions:

loop.sh <PID> truey    1u   REG   0,26        0 15008411 /home/truey/loop.out

Si nous voulons, nous pouvons rediriger stderr vers un autre fichier, si nous voulons utiliser call close(2) et call open(...) encore en utilisant un nom de fichier différent.

Maintenant, le joint bash doit être libéré et nous pouvons quitter gdb:

(gdb) detach
Detaching from program: /bin/bash, process <PID>
(gdb) q

Si le script a été arrêté par gdb à partir d'un autre terminal, il continue à fonctionner. Nous pouvons revenir au terminal de loop.sh. Maintenant, il n'écrit rien à l'écran, mais exécute et écrit dans le fichier. Nous devons le mettre en arrière-plan. Alors appuyez sur ^Z.

^Z
[1]+  Stopped                 ./loop.sh

(Maintenant nous sommes dans le même état que si ^Z a été pressé au début.)

Maintenant, nous pouvons vérifier l'état du travail:

$ ps -f 24522
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
<UID>    <PID><PPID>  0 11:16 pts/36   S      0:00 /bin/bash ./loop.sh
$ jobs
[1]+  Stopped                 ./loop.sh

Le processus doit donc être exécuté en arrière-plan et détaché du terminal. Le nombre dans le jobs la sortie de la commande entre crochets identifie le travail à l'intérieur bash. Nous pouvons utiliser dans ce qui suit construit dans bash commandes qui appliquent un signe '%' avant le numéro du travail:

$ bg %1
[1]+ ./loop.sh &
$ disown -h %1
$ ps -f <PID>
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
<UID>    <PID><PPID>  0 11:16 pts/36   S      0:00 /bin/bash ./loop.sh

Et maintenant nous pouvons quitter le bash appelant. Le processus continue à fonctionner en arrière-plan. Si nous quittons son PPID, devenez 1 (processus init (1)) et le terminal de contrôle devient inconnu.

$ ps -f <PID>
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
<UID>    <PID>     1  0 11:16 ?        S      0:00 /bin/bash ./loop.sh
$ /usr/bin/lsof -p <PID>
...
loop.sh <PID> truey    0u   CHR 136,36                38 /dev/pts/36 (deleted)
loop.sh <PID> truey    1u   REG   0,26     1127 15008411 /home/truey/loop.out
loop.sh <PID> truey    2u   CHR 136,36                38 /dev/pts/36 (deleted)

COMMENTAIRE

Le contenu gdb peut être automatisé en créant un fichier (par exemple loop.gdb) contenant les commandes et en cours d'exécution gdb -q -x loop.gdb -p <PID>. Mon loop.gdb ressemble à ceci:

call close(1)
call open("loop.out", 01102, 0600)
# call close(2)
# call open("loop.err", 01102, 0600)
detach
quit

Ou on peut utiliser la doublure suivante à la place:

gdb -q -ex 'call close(1)' -ex 'call open("loop.out", 01102, 0600)' -ex detach -ex quit -p <PID>

J'espère que c'est une description assez complète de la solution.


21
2017-10-10 09:35



Pour envoyer un processus en cours à nohup (http://en.wikipedia.org/wiki/Nohup)

nohup -p pid , ça n'a pas marché pour moi

Ensuite, j'ai essayé les commandes suivantes et cela a très bien fonctionné

  1. Exécutez SOMECOMMAND, dire /usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1.

  2. Ctrl+Z pour arrêter (pause) le programme et revenir à la coquille.

  3. bg pour l'exécuter en arrière-plan.

  4. disown -h de sorte que le processus ne soit pas tué lorsque le terminal se ferme.

  5. Type exit pour sortir de la coquille parce que maintenant vous êtes prêt à partir car l'opération se déroulera en arrière-plan dans son propre processus, de sorte qu'il n'est pas lié à un shell.

Ce processus est l'équivalent de courir nohup SOMECOMMAND.


6
2017-09-27 06:48



Sur mon système AIX, j'ai essayé

nohup -p  processid>

Cela a bien fonctionné. Il a continué à exécuter mon processus même après la fermeture des fenêtres de terminal. Nous avons ksh comme shell par défaut de sorte que le bg et disown les commandes ne fonctionnaient pas.


1
2018-03-03 16:16



  1. ctrl + z  - Cela va mettre en pause le travail (ne va pas annuler!)
  2. bg - Cela va mettre le travail en arrière-plan et revenir en cours d'exécution
  3. disown -a - ceci coupera toute la pièce jointe avec le travail (ainsi vous pouvez fermer le terminal et il fonctionnera toujours)

Ces étapes simples vous permettront de fermer le terminal tout en maintenant le processus en cours.

Il ne sera pas mis sur nohup (Selon ma compréhension de votre question, vous n'en avez pas besoin ici).


1
2018-03-24 17:06



Cela a fonctionné pour moi sur Ubuntu linux alors que dans tcshell.

  1. CtrlZ pour faire une pause

  2. bg courir en arrière-plan

  3. jobs pour obtenir son numéro d'emploi

  4. nohup %n où n est le numéro d'emploi


0
2017-08-04 22:57