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.
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.
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.
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.
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
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.
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
Dupx est un simple utilitaire * nix pour rediriger la sortie/entrée/erreur standard d'un processus déjà en cours d'exécution.