Rediriger STDERR / STDOUT D'un processus après son démarrage, en utilisant la ligne de commande?

Dans le shell, vous pouvez faire une redirection, > <, etc., mais que diriez-vous après le démarrage d'un programme?

Voici comment je suis venu poser cette question, un programme en cours d'exécution en arrière-plan de mon terminal continue de sortir du texte ennuyeux. C'est un processus important, donc je dois ouvrir un autre shell pour éviter le texte. J'aimerais pouvoir >/dev/null ou une autre redirection afin que je puisse continuer à travailler dans le même shell.

105
demandé sur tijko 2009-02-27 09:26:24

7 réponses

En dehors de la fermeture et de la réouverture de votre tty (c'est-à-dire de la déconnexion et de la réactivation, ce qui peut également mettre fin à certains de vos processus d'arrière-plan dans le processus), il ne vous reste plus qu'un choix:

  • attachez au processus en question en utilisant gdb, et exécutez:
    • P dup2 (open ("/dev / null", 0), 1)
    • P dup2 (open ("/dev / null", 0), 2)
    • détacher
    • quitter

Par exemple:

$ tail -f /var/log/lastlog &
[1] 5636

$ ls -l /proc/5636/fd
total 0
lrwx------ 1 myuser myuser 64 Feb 27 07:36 0 -> /dev/pts/0
lrwx------ 1 myuser myuser 64 Feb 27 07:36 1 -> /dev/pts/0
lrwx------ 1 myuser myuser 64 Feb 27 07:36 2 -> /dev/pts/0
lr-x------ 1 myuser myuser 64 Feb 27 07:36 3 -> /var/log/lastlog

$ gdb -p 5636
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Attaching to process 5636
Reading symbols from /usr/bin/tail...(no debugging symbols found)...done.
Reading symbols from /lib/librt.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/librt.so.1
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/libpthread.so.0...(no debugging symbols found)...done.
[Thread debugging using libthread_db enabled]
[New Thread 0x7f3c8f5a66e0 (LWP 5636)]
Loaded symbols for /lib/libpthread.so.0
Reading symbols from /lib/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2

(no debugging symbols found)
0x00007f3c8eec7b50 in nanosleep () from /lib/libc.so.6

(gdb) p dup2(open("/dev/null",0),1)
[Switching to Thread 0x7f3c8f5a66e0 (LWP 5636)]
$1 = 1

(gdb) p dup2(open("/dev/null",0),2)
$2 = 2

(gdb) detach
Detaching from program: /usr/bin/tail, process 5636

(gdb) quit

$ ls -l /proc/5636/fd
total 0
lrwx------ 1 myuser myuser 64 Feb 27 07:36 0 -> /dev/pts/0
lrwx------ 1 myuser myuser 64 Feb 27 07:36 1 -> /dev/null
lrwx------ 1 myuser myuser 64 Feb 27 07:36 2 -> /dev/null
lr-x------ 1 myuser myuser 64 Feb 27 07:36 3 -> /var/log/lastlog
lr-x------ 1 myuser myuser 64 Feb 27 07:36 4 -> /dev/null
lr-x------ 1 myuser myuser 64 Feb 27 07:36 5 -> /dev/null

Vous pouvez également envisager:

  • en utilisant screen; écran fournit plusieurs TTYs virtuels que vous pouvez basculer entre sans avoir à ouvrir de nouvelles sessions SSH/telnet/etc
  • en utilisant nohup; cela vous permet de fermer et de rouvrir votre session sans perdre de processus d'arrière-plan dans le... processus.
107
répondu vladr 2015-02-24 14:23:28

Cela fera:

strace -ewrite -p $PID

Ce n'est pas si propre (montre des lignes comme: write(#,<text you want to see>)), mais fonctionne!


Vous pourriez aussi ne pas aimer le fait que les arguments sont abrégés. Pour contrôler cela, utilisez le paramètre -s qui définit la longueur maximale des chaînes affichées.

Il attrape tous les flux, donc vous pourriez vouloir filtrer cela d'une manière ou d'une autre:

strace -ewrite -p $PID 2>&1 | grep "write(1" 

Affiche uniquement les appels du descripteur 1. {[4] } est de rediriger STDERR vers STDOUT, car strace écrit dans STDERR par défaut.

55
répondu naugtur 2012-01-26 13:48:24

Riffing au large de vladr (et d'autres) excellente recherche:

Créez les deux fichiers suivants dans le même répertoire, quelque chose dans votre chemin, disons $HOME / bin:

Silence.gdb, contenant (de la réponse de vladr):


p dup2(open("/dev/null",0),1)
p dup2(open("/dev/null",0),2)
detach
quit

Et silence, contenant:


#!/bin/sh
if [ "$0" -a "$1" ]; then
 gdb -p $1 -x $0.gdb
else
 echo Must specify PID of process to silence >&2
fi

chmod +x ~/bin/silence  # make the script executable

Maintenant, La prochaine fois que vous oubliez de rediriger firefox, par exemple, et votre terminal commence à être encombré avec l'inévitable "(firefox-bin: 5117): Gdk-WARNING**: XID collision, trouble ahead" messages:


ps  # look for process xulrunner-stub (in this case we saw the PID in the error above)
silence 5117  # run the script, using PID we found

Vous pouvez également rediriger la sortie de gdb vers/dev / null si vous ne voulez pas la voir.

18
répondu jcomeau_ictx 2010-11-01 08:09:46

Rediriger la sortie d'un processus en cours vers un autre terminal, fichier ou écran:

tty
ls -l /proc/20818/fd
gdb -p 20818

Dans gdb:

p close(1)
p open("/dev/pts/4", 1)
p close(2)
p open("/tmp/myerrlog", 1)
q

Détachez un processus en cours d'exécution du terminalbash et maintenez-le en vie:

[Ctrl+z]
bg %1 && disown %1
[Ctrl+d]

Explication:

20818-juste un exemple d'exécution du processus pid
P-affiche le résultat de la commande gdb
Fermer (1) - fermer la sortie standard
/dev/pts/4 - terminal à écrire
fermer (2) - fermer la sortie d'erreur
/ tmp / myerrlog - fichier à écrire à
q-quitter gdb
bg % 1-exécuter le travail arrêté 1 en arrière-plan
désactiver %1-détacher le travail 1 du terminal

14
répondu Mirek 2010-09-30 20:31:55

Pas une réponse directe à votre question, mais c'est une technique que j'ai trouvée utile ces derniers jours: exécutez la commande initiale en utilisant 'screen', puis détachez.

3
répondu Roger Lipscombe 2009-02-27 07:00:53

Ceci est une partie de script bash basée sur les réponses précédentes, qui redirige le fichier journal lors de l'exécution d'un processus ouvert, il est utilisé comme postscript dans logrotate processus

#!/bin/bash

pid=$(cat /var/run/app/app.pid)
logFile="/var/log/app.log"

reloadLog()
{
    if [ "$pid" = "" ]; then
        echo "invalid PID"
    else
        gdb -p $pid >/dev/null 2>&1 <<LOADLOG
p close(1)
p open("$logFile", 1)
p close(2)
p open("$logFile", 1)
q
LOADLOG
        LOG_FILE=$(ls /proc/${pid}/fd -l | fgrep " 1 -> " | awk '{print $11}')
        echo "log file set to $LOG_FILE"
    fi
}

reloadLog
2
répondu Mostafa Nazari 2018-09-13 10:46:23

Dupx est un simple utilitaire * nix pour rediriger la sortie/entrée/erreur standard d'un processus déjà en cours d'exécution.

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

0
répondu eMPee584 2017-11-29 01:53:30