Question

J'ai un processus en cours d'exécution depuis longtemps et je ne veux pas y mettre fin.

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

Était-ce utile?

La solution

Utilisation du Contrôle des travaux de bash pour envoyer le processus dans le fond:

  1. Ctrl + Z pour arrêter (mettre en pause) le programme et revenir au shell.
  2. bg pour l'exécuter en arrière-plan.
  3. disown -h [job-spec] où [spéc-type de travail] est le numéro du travail (comme %1 pour le premier travail en cours d'exécution; recherchez votre numéro à l'aide de la commande jobs) afin que le travail ne soit pas supprimé à la fermeture du terminal .

Autres conseils

Supposons que, pour une raison quelconque, Ctrl + Z ne fonctionne pas non plus, accédez à un autre terminal, recherchez l'identifiant du processus (avec ps) et exécutez:

kill -SIGSTOP PID 
kill -SIGCONT PID

SIGSTOP suspend le processus et SIGCONT le reprend en arrière-plan. Alors maintenant, la fermeture de vos deux terminaux n’arrête pas votre processus.

La commande permettant de séparer un travail en cours d'exécution du shell (= = nohup) est disown et une commande shell de base.

De bash-manpage (man bash):

  

désavoué [-ar] [-h] [jobspec ...]

     

Sans options, chaque tâche spécifiée est supprimée du tableau des tâches actives. Si l'option -h est donnée, chaque jobpec 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 aucun jobpec n'est   Si l'option -a ou l'option -r n'est pas fournie, le travail en cours est utilisé. Si aucun jobpec n’est fourni, l’option -a   moyen de supprimer ou de marquer tous les travaux; l'option -r sans l'argument jobspec limite l'opération à l'exécution des travaux. Le retour   la valeur est 0 sauf si un jobpec ne spécifie pas de travail valide.

Cela signifie qu’un simple

disown -a

supprimera toutes les tâches de la table des tâches et les rendra nulles

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

Vous ne pouvez pas disown créer un pid ou un processus, vous <=> un travail, et c'est une distinction importante.

Un travail est une notion de processus attaché à un shell. Vous devez donc le jeter en arrière-plan (pas le suspendre), puis le renier.

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 du contrôle des tâches Unix.

Malheureusement, disown est spécifique à bash et n'est pas disponible dans tous les shells.

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

nohup -p pid

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

La réponse du nœud 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 & Amp; Linux , mais ce n’est pas non plus complet. Je voudrais fusionner ces deux solutions. La voici:

Pour mon test, j'ai créé un petit script bash appelé loop.sh, qui affiche son pid avec une minute de sommeil dans une boucle infinie.

$./loop.sh

Maintenant, récupérez le PID de ce processus d’une manière ou d’une autre. Habituellement, ps -C loop.sh est suffisant, mais il est imprimé dans mon cas.

Nous pouvons maintenant passer à un autre terminal (ou appuyer sur ^ Z et dans le même terminal). Maintenant, gdb doit être associé à ce processus.

$ gdb -p <PID>

Ceci arrête le script (s'il est en cours d'exécution). Son état peut être vérifié par ps -f <PID>, où le champ STAT 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

Fermer (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_APPEND.

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 nohup, comme le ferait man open(2), mais cela n'est pas suggéré par call perror(""), en raison de problèmes NFS possibles.

Si nous obtenons -1 comme valeur de retour, alors p errno affiche le message d'erreur. Si nous avons besoin du code d'erreur, utilisez /usr/sbin/lsof -p <PID> la commande gdb.

Nous pouvons maintenant vérifier le fichier récemment redirigé. call close(2) impressions:

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

Si nous le voulons, nous pouvons rediriger stderr vers un autre fichier, si nous voulons utiliser call open(...) et bash à nouveau en utilisant un nom de fichier différent.

Il faut maintenant libérer le fichier attaché ^Z et nous pouvons quitter jobs:

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

Si le script a été arrêté par gdb -q -x loop.gdb -p <PID> à partir d'un autre terminal, il continue de s'exécuter. Nous pouvons revenir au terminal de loop.sh. Maintenant, il n’écrit plus rien à l’écran, mais s’écrit et s’écrit dans le fichier. Nous devons le mettre en arrière-plan. Alors appuyez sur <=>.

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

(Nous sommes maintenant dans le même état que si <=> avait été enfoncé au début.)

Nous pouvons maintenant 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 entre crochets dans la sortie de la commande <=> identifie le travail contenu dans <=>. Nous pouvons utiliser dans les suivantes <=> commandes intégrées portant le signe '%' avant le numéro de 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 la bash d’appel. Le processus continue de s'exécuter en arrière-plan. Si nous quittons son PPID, il devient 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 de gdb peut être automatisé en créant un fichier (par exemple, loop.gdb) contenant les commandes, puis en exécutant <=>. 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

Vous pouvez également utiliser le liner suivant:

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

J'espère qu'il s'agit d'une description assez complète de la solution.

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

nohup -p pid, cela n'a pas fonctionné pour moi

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

  1. Lancez un certain SOMECOMMAND, dire /usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1.

  2. Ctrl + Z pour arrêter (mettre en pause) le programme et revenir au shell.

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

  4. disown -h afin que le processus ne soit pas tué à la fermeture du terminal.

  5. Tapez exit pour sortir du shell, car vous pouvez maintenant y aller car l'opération s'exécute en arrière-plan dans son propre processus, elle n'est donc pas liée à un shell.

Ce processus équivaut à exécuter nohup SOMECOMMAND.

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 du terminal. Nous avons ksh comme shell par défaut pour que les commandes bg et disown ne fonctionnent pas.

  1. ctrl + z - le travail sera mis en pause (ne sera pas annulé!)
  2. bg - cela mettra le travail en arrière-plan et reviendra dans le processus en cours
  3. disown -a - Ceci coupera toute la pièce jointe avec le travail (vous pourrez donc fermer le terminal et le lancer encore)

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

Il ne sera pas mis sur nohup (d'après ce que j'ai compris de votre question, vous n'en avez pas besoin ici).

Cela a fonctionné pour moi sur Ubuntu Linux tout en tcshell.

  1. Ctrl Z pour le suspendre

  2. bg à exécuter en arrière-plan

  3. jobs pour obtenir son numéro de travail

  4. nohup %n où n est le numéro de travail

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top