Zum Anzeigen an eine Prozessausgabe anhängen


110

Wie würde ich eine Konsolen- / Terminalansicht an eine Anwendungsausgabe anhängen, damit ich sehen kann, was sie möglicherweise sagt?

Wie würde ich mich von einer Anwendungsausgabe trennen, ohne die Anwendung zu beenden?

Wenn Sie eine gesprächige Anwendung über die Befehlszeile starten, sehen Sie normalerweise alle Arten von wunderbaren Ausgaben. Nehmen wir jedoch an, ich habe eine besonders gesprächige Programmierung wie KINO und möchte die Ausgabe jederzeit anzeigen, ohne sie über die Befehlszeile neu zu starten. Ich kann nicht; Zumindest weiß ich nicht wie.


1
Haben Sie ein Debug-Symbol in Ihrem Prozess? Läuft es in der Produktionsumgebung? Und wenn ja, brauchen Sie es, um NIE angehalten zu werden?
Yves Baumes

Wenn ich Probleme mit der Stabilität von Endbenutzerprogrammen wie kino habe (stürzt ab und tötet meinen Sound), möchte ich wissen können, wie / warum es abgestürzt ist, damit ich daran arbeiten kann, es zu beheben. Dies ist kein Programm, das ich entwickle, sondern eine Technik, die ich gerne zur Fehlerbehebung kennen würde. Ich werde Ihren Vorschlag unten versuchen.
Aggitan

Antworten:


17

Hier gibt es einige Möglichkeiten. Eine besteht darin, die Ausgabe des Befehls in eine Datei umzuleiten und dann mit 'tail' neue Zeilen anzuzeigen, die dieser Datei in Echtzeit hinzugefügt werden.

Eine andere Möglichkeit besteht darin, Ihr Programm innerhalb von 'screen' zu starten, einer Art textbasierten Terminal-Anwendung. Bildschirmsitzungen können angehängt und getrennt werden, sind jedoch nominell nur für den Gebrauch durch denselben Benutzer gedacht. Wenn Sie sie also zwischen Benutzern teilen möchten, ist dies ein großes Problem.


1
"Hier gibt es einige Optionen. Eine besteht darin, die Ausgabe des Befehls in eine Datei umzuleiten und dann mit 'tail' neue Zeilen anzuzeigen, die dieser Datei in Echtzeit hinzugefügt werden." Kann dies mit bereits laufenden Anwendungen durchgeführt werden?
Aggitan

2
Sie benötigen wahrscheinlich tail -f $ log_file, um die Ausgabe zu erhalten, wie sie in die Datei geschrieben ist. Nein, ich weiß auch nicht, wie ich das mit einer bereits laufenden App machen kann.
Varkhan

@aggitan: Nein. Bei vorhandenen Anwendungen müssen Sie diese neu starten, da sie ihre E / A bereits an das steuernde Terminal gebunden haben.
Don Werve


286

Ich denke, ich habe hier eine einfachere Lösung. Suchen Sie einfach unter dem Pseudodateisystem, auf das Sie unter dem /procPfad zugreifen können, nach einem Verzeichnis, dessen Name der gesuchten PID entspricht . Wenn Sie also ein Programm mit der ID 1199 ausführen, wird Folgendes ausgeführt cd:

$ cd /proc/1199

Suchen Sie dann nach dem fdVerzeichnis darunter

$ cd fd

Dieses fdVerzeichnis enthält die Dateideskriptorobjekte, die Ihr Programm verwendet (0: stdin, 1: stdout, 2: stderr) und genau tail -fdas, was Sie benötigen - in diesem Fall stdout):

$ tail -f 1

9
Ich konnte nicht verwenden, tailda in meinem Fall die Ausgabe zur Eingabe an einen anderen Prozess umgeleitet wurde, morezeigte mir jedoch die aktuellen Daten.
Ωmega

10
Einer der spannendsten Beiträge auf dieser Seite!
Robert

2
morearbeitet für mich. Ubuntu 14.04 auf einem Knotenprozess
Shih-Min Lee

1
Dies funktioniert bei einem Java-Prozess, der System.out.println aufruft, nicht. Es gibt überhaupt keine Ausgabe an / proc / [pid] / fd / 1
Nick

1
Versucht, eine Reproduktion mit den folgenden zu erstellen, aber ohne Erfolg: `` `Docker-Run -it - Name Container1 Ubuntu Bash -c -i" COUNT = 0; während wahr; Echo Echo Halten Sie den Dancefloor-Beat am Laufen; (( COUNT ++)); sleep 1; echo \ "Count is: \ $ {COUNT} \"; done; " `` `In einem anderen Terminal:` `` Docker exec -it container1 tail -f / proc / 1 / fd / 1 `` `
JacobWuzHere

54

Ich habe genau das Gleiche gesucht und festgestellt, dass Sie Folgendes tun können:

strace -ewrite -p $PID

Es ist nicht genau das, was Sie brauchten, aber es ist ziemlich nah.

Ich habe versucht, die Ausgabe umzuleiten, aber das hat bei mir nicht funktioniert. Vielleicht, weil der Prozess in eine Steckdose schrieb, weiß ich es nicht.


danke, es funktioniert, aber die Ausgabe wird abgeschnitten, z. B. für ping: write (1, "64 Bytes von 1.0.0.1: icmp_seq =" ..., 56) = 56
izy

8

Wie würde ich eine Konsolen- / Terminalansicht an eine Anwendungsausgabe anhängen, damit ich sehen kann, was sie möglicherweise sagt?

Zu dieser Frage weiß ich, dass es möglich ist, die Ausgabe abzufangen, selbst wenn Sie den Befehl sceen vor dem Starten des Prozesses nicht gestartet haben.

Obwohl ich es nie ausprobiert habe, habe ich einen interessanten Artikel gefunden, in dem erklärt wird, wie GDB verwendet wird (und ohne den Prozess neu zu starten).

Umleiten der Ausgabe von einem laufenden Prozess

Grundsätzlich:

  1. Überprüfen Sie die Liste der geöffneten Dateien für Ihren Prozess dank / proc / xxx / fd
  2. Anfügen Ihren Prozess mit GDB hinzu
  3. Schließen Sie während der Pause die Datei, an der Sie interessiert sind, und rufen Sie die Funktion close () auf (Sie können jede Funktion Ihres Prozesses in GDB ausführen. Ich vermute, Sie benötigen Debug-Symbole in Ihrem Prozess.)
  4. Öffnen Sie eine neue Datei, die die Funktion create () oder open () aufruft . ( Werfen Sie einen Blick in die Kommentare am Ende. Sie werden sehen, dass die Leute vorschlagen, dup2 () zu verwenden, um sicherzustellen, dass dasselbe Handle verwendet wird.)
  5. Trennen Sie den Prozess und lassen Sie ihn laufen.

Übrigens, wenn Sie ein Linux-Betriebssystem unter i386 ausführen, sprechen Kommentare von einem besseren Tool, um die Ausgabe auf eine neue Konsole umzuleiten: 'retty' . Wenn ja, ziehen Sie die Verwendung in Betracht.


5

Für mich hat das funktioniert:

  1. Melden Sie sich als Eigentümer des Prozesses an (sogar rootdie Erlaubnis wird verweigert)

    ~$ su - process_owner
    
  2. Beenden Sie den Dateideskriptor wie in vielen anderen Antworten erwähnt.

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

2

Ich wollte einen lokal ausgeführten Yum-Upgrade-Prozess aus der Ferne verfolgen. Obwohl es wahrscheinlich effizientere Möglichkeiten gab, dies zu tun, habe ich Folgendes getan:

watch cat /dev/vcsa1

Natürlich möchten Sie vcsa2, vcsa3 usw. verwenden, je nachdem, welches Terminal verwendet wurde.

Solange mein Terminalfenster dieselbe Breite hatte wie das Terminal, auf dem der Befehl ausgeführt wurde, konnte ich alle zwei Sekunden einen Schnappschuss der aktuellen Ausgabe sehen. Die anderen an anderer Stelle empfohlenen Befehle funktionierten für meine Situation nicht besonders gut, aber dieser hat den Trick gemacht.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.