Comment puis-je 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 y mettre fin.
Comment puis-je le mettre sous nohup (c'est-à-dire, comment puis-je le faire continuer à fonctionner même si je ferme le terminal?)
10 réponses
utilisant le Job Control de bash pour envoyer le processus dans l'arrière-plan:
- Ctrl + Z pour arrêter (pause) le programme et revenir à l'interpréteur de commandes.
-
bg
pour l'exécuter en arrière-plan. -
disown -h [job-spec]
où [job-spec] est le numéro d'emploi (comme%1
pour le premier emploi en cours d'exécution; trouver à propos de votre numéro avec lejobs
) afin que le travail ne soit pas tué lorsque le terminal ferme.
Suppose pour une raison quelconque Ctrl + Z ne fonctionne pas non plus, aller à un autre terminal, trouver le numéro du processus (en utilisant ps
) et exécuter:
kill -20 PID
kill -18 PID
kill -20
( SIGTSTP
) va suspendre le processus et kill -18
( SIGCONT
) va reprendre le processus, en arrière-plan.
Donc maintenant, fermer vos deux terminaux n'arrêtera pas votre processus.
la commande pour séparer un travail en cours d'exécution du shell ( = le rend nohup) est disown
et une commande-shell de base.
De bash-page de manuel (man bash):
désavouer [ar] [-h] [jobspec ...]
sans options, chaque jobspec est retiré du tableau des emplois actifs. Si l'option-h est donnée, chaque jobspec n'est pas retiré de la table, mais est marqué de sorte que SIGHUP ne soit pas envoyé à la tâche si le shell reçoit un soupir. Si aucun jobpec n'est l'emploi actuel est utilisé, et ni l'option-a ni l'option-r ne sont fournies. Si aucun jobpec n'est fourni, l'option-a signifie supprimer ou marquer tous les emplois; l'option-r sans argument jobspec restreint l'exploitation aux emplois courants. Retour la valeur est 0 sauf si un jobspec ne spécifie pas un emploi valide.
cela signifie qu'un simple
disown -a
va supprimer tous les emplois de la cents cinquante et une million neuf cent trente mille neuf cent vingt"
ce sont de bonnes réponses ci-dessus, je voulais juste ajouter une clarification:
Vous ne pouvez pas disown
un pid ou un processus, disown
un travail, et c'est une distinction importante.
un travail est quelque chose qui est une notion d'un processus qui est attaché à un shell, donc vous devez jeter le travail à l'arrière-plan (pas le suspendre) et ensuite le rejeter.
Question:
% 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 sur le contrôle des tâches Unix.
Unrfortunately disown
est spécifique à bash et ne sont pas disponibles dans tous les shells.
certaines saveurs 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
la réponse de noeud est vraiment grande, mais il a laissé ouvert la question Comment peut obtenir stdout et stderr redirigé. J'ai trouvé une solution sur Unix & Linux , mais elle n'est pas non plus complète. Je voudrais fusionner ces deux solutions. Le voici:
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 obtenir le PID de ce processus d'une certaine manière. Généralement ps -C loop.sh
est assez bon, mais il est imprimé dans mon cas.
maintenant nous pouvons passer à un autre terminal (ou appuyez sur ^Z et dans le même terminal). Maintenant gdb
devrait être attaché à ce processus.
$ gdb -p <PID>
ceci arrête le script (s'il tourne). 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)
= 0
À proximité(1) renvoie zéro en cas de succès.
(gdb) call open("loop.out", 01102, 0600)
= 1
Ouvrir (1) renvoie le nouveau descripteur de fichier s'il est réussi.
Cette ouverture est égal à 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 /usr/include/bits/fcntl.h fichier d'en-tête.
la sortie le fichier peut être ouvert avec O_APPEND
, nohup
allait faire, mais ce n'est pas suggéré par man open(2)
, en raison de possibles problèmes NFS.
si nous obtenons -1 comme valeur de retour, alors call perror("")
affiche 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>
imprime:
loop.sh <PID> truey 1u REG 0,26 0 15008411 /home/truey/loop.out
si nous voulons, nous pouvons rediriger stderr vers un autre file, si nous voulons utiliser call close(2)
et call open(...)
à nouveau en utilisant un nom de fichier différent.
maintenant le bash
ci-joint 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
d'un autre terminal, il continue à fonctionner. On peut revenir à loop.sh le terminal. Maintenant, il n'écrit plus rien à l'écran, mais exécute et écrit dans le fichier. Nous devons le mettre dans le fond. 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
ainsi le processus doit être exécuté en arrière-plan et détaché du terminal. Le numéro entre crochets de la commande jobs
identifie le travail à l'intérieur de bash
. Nous pouvons utiliser dans les suivants construit en bash
commandes appliquant un 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, on peut arrêter la fête de l'appel. Le processus est encore en cours d'exécution en arrière-plan. Si nous quittons son PPID 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 truc gdb peut être automatisé en créant un fichier (par exemple boucle.gdb) contenant les commandes et lancez gdb -q -x loop.gdb -p <PID>
. Ma boucle.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.
pour envoyer processus en cours d'exécution à nohup ( http://en.wikipedia.org/wiki/Nohup )
nohup -p pid
, il n'a pas fonctionné pour moi
puis j'ai essayé les commandes suivantes et ça a très bien fonctionné
-
Run some SOMECOMMAND, dis
/usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1
. -
Ctrl + Z à l'arrêt (pause) le programme et revenir au shell.
-
bg
pour l'exécuter en arrière-plan. -
disown -h
pour que le processus ne soit pas tué quand le terminal ferme. -
Type
exit
pour sortir du shell parce que maintenant vous êtes bon à aller car l'opération va courir en arrière-plan dans son propre processus, donc il n'est pas lié à un shell.
ce processus est l'équivalent de 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 donc les commandes bg
et disown
n'ont pas fonctionné.
- Ctrl + z - cela va interrompre le travail (ne va pas annuler!)
-
bg
- cela placera le travail en arrière-plan et le retour dans le processus en cours d'exécution -
disown -a
- cela va couper toute la fixation avec job (de sorte que vous pouvez fermer le terminal et il fonctionnera toujours)
ces simples étapes vous permettront de fermer le terminal tout en gardant processus en cours d'exécution.
il ne mettra pas sur nohup
(basé sur ma compréhension de votre question, vous n'en avez pas besoin ici).
cela a fonctionné pour moi sur Ubuntu linux tout en tcshell.
-
Ctrl Z mettre en pause
-
bg
pour exécuter en arrière-plan -
jobs
pour obtenir son numéro d'emploi -
nohup %n
où n est le numéro d'emploi