Comment rediriger la sortie d'un processus en cours d'exécution [dupliquer]
Cette question a déjà une réponse ici:
- rediriger STDERR / STDOUT D'un processus après son démarrage, en utilisant la ligne de commande? 7 réponses
Normalement, je commencerais une commande comme
longcommand &;
Je sais que vous pouvez le rediriger en faisant quelque chose comme
longcommand > /dev/null;
Par exemple pour se débarrasser de la sortie ou
longcommand 2>&1 > output.log
Pour capturer sortie.
Mais j'oublie parfois, et je me demandais s'il y avait un moyen de capturer ou de rediriger après le fait.
longcommand
ctrl-z
bg 2>&1 > /dev/null
Ou quelque chose comme ça pour que je puisse continuer à utiliser le terminal sans que des messages apparaissent sur le terminal.
5 réponses
Voir Redirection de la Sortie d'un Processus en cours d'Exécution.
Tout d'abord, j'exécute la commande
cat > foo1
en une session et teste que les données de stdin sont copiées dans le fichier. Ensuite, dans une autre session, je redirige la sortie.Tout D'abord trouver le PID du processus:
$ ps aux | grep cat rjc 6760 0.0 0.0 1580 376 pts/5 S+ 15:31 0:00 cat
Vérifiez maintenant les poignées de fichiers qu'il a Ouvertes:
$ ls -l /proc/6760/fd total 3 lrwx—— 1 rjc rjc 64 Feb 27 15:32 0 -> /dev/pts/5 l-wx—— 1 rjc rjc 64 Feb 27 15:32 1 -> /tmp/foo1 lrwx—— 1 rjc rjc 64 Feb 27 15:32 2 -> /dev/pts/5
Lancez maintenant GDB:
$ gdb -p 6760 /bin/cat GNU gdb 6.4.90-debian [license stuff snipped] Attaching to program: /bin/cat, process 6760 [snip other stuff that's not interesting now] (gdb) p close(1) $1 = 0 (gdb) p creat("/tmp/foo3", 0600) $2 = 1 (gdb) q The program is running. Quit anyway (and detach it)? (y or n) y Detaching from program: /bin/cat, process 6760
La commande
p
dans GDB affichera la valeur d'une expression, expression peut être une fonction à appeler, il peut s'agir d'un appel système... donc j'exécute un appel systèmeclose()
et passe le handle de fichier 1, puis j'exécute un appel systèmecreat()
pour ouvrir un nouveau fichier. Le résultat decreat()
était 1, ce qui signifie qu'il a remplacé le handle de fichier précédent. Si je voulais utiliser le même fichier pour stdout et stderr ou si je voulais remplacer un handle de fichier par un autre numéro, je devrais appeler l'appel systèmedup2()
pour obtenir ce résultat.Pour cet exemple j'ai choisi d'utiliser
creat()
au lieu deopen()
, car il y a moins de paramètres. Les macros C pour les drapeaux ne sont pas utilisables à partir de GDB (il n'utilise pas D'en – têtes C) donc je devrais lire les fichiers d'en-tête pour découvrir cela-ce n'est pas si difficile à faire mais cela prendrait plus de temps. Notez que 0600 est l'autorisation octale pour le propriétaire ayant un accès en lecture/écriture et le groupe et d'autres n'ayant pas accès. Cela fonctionnerait également d'utiliser 0 pour ce paramètre et d'exécuter chmod sur le fichier plus tard.Après cela, je vérifie le résultat:
ls -l /proc/6760/fd/ total 3 lrwx—— 1 rjc rjc 64 2008-02-27 15:32 0 -> /dev/pts/5 l-wx—— 1 rjc rjc 64 2008-02-27 15:32 1 -> /tmp/foo3 <==== lrwx—— 1 rjc rjc 64 2008-02-27 15:32 2 -> /dev/pts/5
Taper plus de données dans
cat
entraîne l'ajout du fichier/tmp/foo3
.Si vous voulez fermer la session d'origine, vous devez fermer tous les handles de fichiers pour elle, ouvrez un nouveau périphérique qui peut être le tty de contrôle, puis appelez
setsid()
.
Dupx
Dupx est un utilitaire *Nix simple pour rediriger la sortie/entrée/erreur standard d'un processus déjà en cours d'exécution.
Motivation
Je me suis souvent retrouvé dans une situation où un processus que j'ai commencé sur un système distant via SSH prend beaucoup plus de temps que prévu. J'ai besoin de casser la connexion SSH, mais si je le fais, le processus mourra s'il essaie d'écrire quelque chose sur stdout/error d'un tuyau cassé. J'aimerais pouvoir suspendre le processus avec ^Z et ensuite, faites un
bg %1 >/tmp/stdout 2>/tmp/stderr
Malheureusement, cela ne fonctionnera pas (dans les coquilles que je connais).
Vous pouvez aussi le faire en utilisant reredirect (https://github.com/jerome-pouiller/reredirect/).
De Type
reredirect -m FILE PID
Et les sorties (standard et erreur) seront écrites dans le fichier.
Reredirect README explique également comment restaurer l'état d'origine du processus, comment rediriger vers une autre commande ou rediriger uniquement stdout ou stderr.
(reredirect semble avoir les mêmes caractéristiques que Dupx décrit dans une autre réponse mais, cela ne dépend pas de Gdb).
Écran
Si le processus est en cours d'exécution dans une session screen, vous pouvez utiliser la commande screen log pour enregistrer la sortie de cette fenêtre dans un fichier:
Passer à la fenêtre du script, C-a H {[9] } pour se connecter.
Maintenant vous pouvez:
$ tail -f screenlog.2 | grep whatever
De la page de manuel de l'écran:
Journal [on / off]
Démarrer / Arrêter l'écriture de la sortie de la fenêtre en cours dans un fichier " screenlog.n " dans le répertoire par défaut de la fenêtre, où n est le numéro de la fenêtre en cours. Ce le nom de fichier peut être modifié avec la commande 'logfile'. Si aucun paramètre n'est donné, l'état de journalisation est basculé. Le journal de session est ajouté au contenu précédent du fichier s'il existe déjà. Le contenu actuel et le contenu de l'historique de défilement ne sont pas inclus dans le journal de session. Par défaut est "off".
Je suis sûr que tmux a quelque chose de similaire aussi.
J'ai recueilli quelques informations sur internet et préparé le script qui ne nécessite aucun outil externe: Voir ma réponse ici . J'espère que c'est utile.