Attacher à une sortie de processus pour affichage

112

Comment pourrais-je «attacher» une console / vue de terminal à la sortie d'une application pour que je puisse voir ce qu'elle peut dire?

Comment pourrais-je me détacher de la sortie d'une application sans tuer l'application?

Normalement, si vous lancez une application bavarde en utilisant la ligne de commande, vous obtenez toutes sortes de sorties merveilleuses. Cependant, disons que j'ai une programmation particulièrement bavarde en cours d'exécution, comme KINO, et que je veux voir sa sortie à tout moment sans la redémarrer via la ligne de commande. Je ne peux pas; au moins je ne sais pas comment.

aggitan
la source
1
Avez-vous un symbole de débogage dans votre processus? Fonctionne-t-il dans un environnement de production? Et si oui, en avez-vous besoin pour ne JAMAIS être mis en pause?
yves Baumes
Quand j'ai des épisodes de problèmes de stabilité avec des programmes d'utilisateurs finaux comme kino (plante et tue mon son), je veux être en mesure de savoir comment / pourquoi il s'est écrasé afin que je puisse travailler à le réparer. Ce n'est pas un programme que je développe mais une technique que j'aimerais connaître pour le dépannage. Je vais essayer votre suggestion ci-dessous.
aggitan

Réponses:

18

Il y a quelques options ici. La première consiste à rediriger la sortie de la commande vers un fichier, puis à utiliser «tail» pour afficher les nouvelles lignes ajoutées à ce fichier en temps réel.

Une autre option consiste à lancer votre programme à l'intérieur de «screen», qui est une sorte d'application de terminal basée sur du texte. Les sessions d'écran peuvent être attachées et détachées, mais elles sont théoriquement destinées uniquement à être utilisées par le même utilisateur, donc si vous voulez les partager entre utilisateurs, c'est une grosse douleur dans le cul.

Don Werve
la source
1
"Il y a quelques options ici. La première consiste à rediriger la sortie de la commande vers un fichier, puis à utiliser 'tail' pour afficher les nouvelles lignes qui sont ajoutées à ce fichier en temps réel." Cela peut-il être fait avec des applications déjà en cours d'exécution?
aggitan le
2
Vous aurez probablement besoin de tail -f $ log_file pour obtenir la sortie telle qu'elle est écrite dans le fichier. De plus, non, je ne connais aucun moyen de le faire avec une application déjà en cours d'exécution.
Varkhan le
@aggitan: Non. Pour les applications existantes, vous devrez les redémarrer, car elles ont déjà lié leurs E / S au terminal de contrôle.
Don Werve
288

Je pense que j'ai une solution plus simple ici. Recherchez simplement un répertoire dont le nom correspond au PID que vous recherchez, sous le pseudo-système de fichiers accessible sous le /procchemin. Donc, si vous avez un programme en cours d'exécution, dont l'ID est 1199, cddedans:

$ cd /proc/1199

Recherchez ensuite le fdrépertoire en dessous

$ cd fd

Ce fdrépertoire contient les objets descripteurs de fichiers que votre programme utilise (0: stdin, 1: stdout, 2: stderr) et juste tail -fcelui dont vous avez besoin - dans ce cas, stdout):

$ tail -f 1
licorna
la source
9
Je n'ai pas pu utiliser tailcar dans mon cas, la sortie était redirigée vers un autre processus pour l'entrée, mais morem'a montré les données actuelles.
Ωmega
10
L'un des articles les plus fascinants de ce site!
robert
2
moretravaille pour moi. ubuntu 14.04 sur un processus de nœud
Shih-Min Lee
1
Cela ne fonctionne pas pour moi avec un processus java qui appelle System.out.println. Il n'y a pas de sortie du tout vers / proc / [pid] / fd / 1
Nick
1
J'ai essayé de créer une reproduction en utilisant ce qui suit, mais en vain: `` `` docker run -it --name container1 ubuntu bash -c -i "COUNT = 0; while true; do echo Continue le rythme de la piste de danse; (( COUNT ++)); sleep 1; echo \ "Count is: \ $ {COUNT} \"; done; " `` Dans un autre terminal: `` docker exec -it container1 tail -f / proc / 1 / fd / 1 ''
JacobWuzHere
54

Je cherchais exactement la même chose et j'ai trouvé que vous pouviez faire:

strace -ewrite -p $PID

Ce n'est pas exactement ce dont vous aviez besoin, mais c'est assez proche.

J'ai essayé la sortie de redirection, mais cela n'a pas fonctionné pour moi. Peut-être parce que le processus écrivait sur une socket, je ne sais pas.

Paul Scheltema
la source
merci cela fonctionne, mais la sortie est tronquée, par exemple pour ping: write (1, "64 bytes from 1.0.0.1: icmp_seq =" ..., 56) = 56
izy
8

Comment pourrais-je «attacher» une console / vue de terminal à la sortie d'une application pour que je puisse voir ce qu'elle peut dire?

À propos de cette question, je sais qu'il est possible d'attraper la sortie, même si vous n'avez pas lancé la commande sceen avant de lancer le processus.

Bien que je ne l'ai jamais essayé, j'ai trouvé un article intéressant qui explique comment utiliser GDB (et sans redémarrer votre processus).

redirection-de-sortie-d'un-processus-en-cours

Fondamentalement:

  1. Vérifiez la liste des fichiers ouverts pour votre processus, grâce à / proc / xxx / fd
  2. Joindre votre processus avec GDB
  3. Pendant qu'il est en pause, fermez le fichier qui vous intéresse, en appelant la fonction close () (vous pouvez n'importe quelle fonction de votre processus dans GDB. Je suppose que vous avez besoin de symboles de débogage dans votre processus ..)
  4. Ouvrez un nouveau fichier en appelant la fonction create () ou open (). (Regardez dans les commentaires à la fin, vous verrez que les gens suggèrent d'utiliser dup2 () pour s'assurer que le même handle sera utilisé)
  5. Détachez le processus et laissez-le fonctionner.

Au fait, si vous utilisez un système d'exploitation Linux sur i386, les commentaires parlent d'un meilleur outil pour rediriger la sortie vers une nouvelle console: 'retty' . Si tel est le cas, envisagez son utilisation.

Yves Baumes
la source
6

Pour moi, cela a fonctionné:

  1. Connectez-vous en tant que propriétaire du processus (même si l' rootautorisation est refusée)

    ~$ su - process_owner
    
  2. Complétez le descripteur de fichier comme mentionné dans de nombreuses autres réponses.

    ~$ tail -f /proc/<process-id>/fd/1 # (0: stdin, 1: stdout, 2: stderr)
    
akki
la source
2

Je voulais regarder à distance un processus de mise à niveau de yum qui avait été exécuté localement, donc s'il y avait probablement des moyens plus efficaces de le faire, voici ce que j'ai fait:

watch cat /dev/vcsa1

De toute évidence, vous voudrez utiliser vcsa2, vcsa3, etc., en fonction du terminal utilisé.

Tant que la fenêtre de mon terminal était de la même largeur que le terminal sur lequel la commande était exécutée, je pouvais voir un instantané de leur sortie actuelle toutes les deux secondes. Les autres commandes recommandées ailleurs ne fonctionnaient pas particulièrement bien pour ma situation, mais celle-là a fait l'affaire.

Fléau rouge
la source