Dans le shell, vous pouvez effectuer une redirection, >
<
, etc., mais qu'en est-il après le démarrage d'un programme?
Voici comment je suis arrivé à poser cette question: un programme exécuté en arrière-plan de mon terminal continue de générer des textes gênants. C'est un processus important, je dois donc ouvrir un autre shell pour éviter le texte. J'aimerais pouvoir utiliser >/dev/null
ou une autre redirection pour pouvoir continuer à travailler dans le même shell.
À moins de fermer et de rouvrir votre terminal (c'est-à-dire vous déconnecter et vous reconnecter, ce qui peut également mettre fin à certains de vos processus d'arrière-plan au cours du processus), il ne vous reste qu'un choix:
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 considérer:
screen
; L’écran fournit plusieurs TTY virtuels que vous pouvez basculer sans avoir à ouvrir de nouvelles sessions SSH/telnet/etc.Nohup
; Cela vous permet de fermer et de rouvrir votre session sans perdre aucun processus d'arrière-plan dans le processus ....Cela fera:
strace -ewrite -p $PID
Ce n'est pas si propre (affiche des lignes comme: write(#,<text you want to see>)
), mais ça marche!
Vous pourriez également ne pas aimer le fait que les arguments soient abrégés. Pour contrôler cela, utilisez le paramètre -s
qui définit la longueur maximale des chaînes affichées.
Il intercepte tous les flux, vous pouvez donc filtrer cela en quelque sorte:
strace -ewrite -p $PID 2>&1 | grep "write(1"
affiche uniquement les appels du descripteur 1. 2>&1
consiste à rediriger STDERR vers STDOUT, car strace
écrit sur STDERR par défaut.
résumant l'excellente recherche de vladr (et d'autres):
créez les deux fichiers suivants dans le même répertoire, quelque chose dans votre chemin, par exemple $ HOME/bin:
silence.gdb, contenant (d'après 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
Par exemple, la prochaine fois que vous oubliez de rediriger firefox, votre terminal commence à être encombré par l’inévitable "(firefox-bin: 5117): message Gdk-WARNING **: XID collision, trouble ahead":
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.
Redirige la sortie d'un processus en cours d'exécution vers un autre terminal, fichier ou écran:
tty
ls -l /proc/20818/fd
gdb -p 20818
À l'intérieur 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 de bash terminal et maintenez-le actif:
[Ctrl+z]
bg %1 && disown %1
[Ctrl+d]
Explication:
20818 - juste un exemple de processus en cours d'exécution pid
p - résultat d'impression de la commande gdb
close (1) - sortie standard proche
/dev/pts/4 - terminal sur lequel écrire
close (2) - sortie d'erreur close
/tmp/myerrlog - fichier dans lequel écrire
q - quitter Gdb
bg% 1 - exécution du travail 1 arrêté en arrière-plan
disown% 1 - détache le travail 1 du terminal
Ce n’est 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 danslogrotate
process
#!/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
Vous pouvez utiliser reredirect ( https://github.com/jerome-pouiller/reredirect/ ).
Type
reredirect -m FILE PID
et les sorties (standard et erreur) seront écrites dans FILE.
reredirect README explique également comment restaurer l'état initial du processus, rediriger vers une autre commande ou rediriger uniquement stdout ou stderr.
reredirect
fournit également un script appelé relink
qui permet de rediriger vers le terminal actuel:
relink PID
relink PID | grep usefull_content
(reredirect semble avoir les mêmes fonctionnalités que Dupx décrit dans une autre réponse mais cela ne dépend pas de Gdb).
Dupx est un utilitaire simple * nix permettant de rediriger la sortie/entrée/erreur standard d’un processus en cours.