Voir Redirection de la sortie d'un processus en cours d'exécution .
Tout d'abord, je lance la commande
cat > foo1
en une session et testez que les données de stdin sont copiées dans le fichier. Ensuite, dans une autre session, je redirige la sortie.Trouvez d'abord 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 descripteurs de fichiers qu'il a ouverts :
$ 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
Le
p
commande dans GDB imprimera la valeur d'une expression, une expression peut être une fonction à appeler, cela peut être un appel système… J'exécute donc unclose()
appel système et passe le descripteur de fichier 1, puis j'exécute uncreat()
appel système pour ouvrir un nouveau fichier. Le résultat ducreat()
était 1, ce qui signifie qu'il a remplacé le descripteur de fichier précédent. Si je voulais utiliser le même fichier pour stdout et stderr ou si je voulais remplacer un descripteur de fichier par un autre numéro, je devrais appeler ledup2()
appel système 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 le découvrir - 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 les autres n'ayant aucun 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
Saisir plus de données dans
cat
résultats dans le fichier/tmp/foo3
étant ajouté à.Si vous souhaitez fermer la session d'origine, vous devez fermer tous les descripteurs de fichiers, ouvrir un nouveau périphérique qui peut être le tty de contrôle, puis appeler
setsid()
.
Vous pouvez également le faire en utilisant reredirect
(https://github.com/jerome-pouiller/reredirect/).
La commande ci-dessous redirige les sorties (standard et erreur) du processus PID
à FILE
:
reredirect -m FILE PID
Le README
de reredirect
explique également d'autres fonctionnalités intéressantes :comment restaurer l'état d'origine du processus, comment rediriger vers une autre commande ou rediriger uniquement stdout ou stderr.
L'outil fournit également relink
, un script permettant de rediriger les sorties vers le terminal courant :
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).