Comment rediriger la sortie d'un processus en cours d'exécution [dupliquer]

Cette question a déjà une réponse ici:

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.

118
demandé sur Sheldon Ross 2009-08-24 22:27:31

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ème close() et passe le handle de fichier 1, puis j'exécute un appel système creat() pour ouvrir un nouveau fichier. Le résultat de creat() é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ème dup2() pour obtenir ce résultat.

Pour cet exemple j'ai choisi d'utiliser creat() au lieu de open(), 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().

107
répondu user37875 2016-12-15 12:56:17

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).

Http://www.isi.edu/ ~ Yuri / dupx /

13
répondu blah 2011-12-26 18:07:38

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).

11
répondu Jezz 2016-05-06 07:15:57

É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.

6
répondu lemonsqueeze 2016-05-06 02:41:44

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.

0
répondu Krzysztow 2017-03-20 10:04:20