Frage

Ich schreibe einen grafischen URI-Handler für git: // Links mit bash und zenity, und ich bin mit einem zenity ‚text-info‘ Dialog zu zeigen git des Klons ausgegeben, während es läuft, FIFO-Rohrleitungen verwendet wird. Das Skript ist etwa 90 Zeilen lang, also werde ich es nicht stört hier veröffentlichen, aber hier ist die wichtigsten Linien:

git clone "$1" "$target" 2>&1 | cat >> /tmp/githandler-fifo &
cat /tmp/githandler-fifo | zenity --text-info --text='Cloning git repository' &

Ich bin mit FIFO anstelle einer direkten Rohr, damit sie für das Töten von git asynchron und damit laufen, wenn das zenity Fenster geschlossen wird.

Das Problem ist, die einzige Linie, die angezeigt wird von git der Ausgabe ist die erste:

Initialized empty Git repository in /home/delan/a/.git/

Die anderen Linien mit Zählen von Objekten usw. nicht zeigen oder auf dem Endgerät angezeigt.

Aktuelle Grund

Der aktuelle Konsens darüber, warum dies nicht funktionieren scheint, dass cat zu sein ist nicht blockierende und quitt nach der ersten Zeile, vorbei nur, dass zu zenity und nicht den Rest. Mein Ziel ist es für das Lesen zu zwingen, zu blockieren, und zenity Text Info haben Dialog schrittweise alle Ausgaben zeigen.

git Ausgänge Fortschrittsmeldungen (etwas anderes als die „initialisierte“ Nachricht) auf stderr, aber in dem Moment versuche ich Rohr stderr in eine Datei oder fusioniert mit stdout, die Nachrichten verschwinden.

Fix Versuch 1

Ich habe versucht, zwei Sperr Versionen von Katzen Funktionen in C, Brot und bwrite zu schreiben, wie folgt aus:

#include <stdio.h>
main(int argc, char **argv) {
    int c;
    for (;;) {
        freopen(argv[1], "r", stdin);
        while ((c = getchar()) != EOF)
            putchar(c);
    }
}

#include <stdio.h>
main(int argc, char **argv) {
    int c;
    for (;;) {
        freopen(argv[1], "w", stdout);
        while ((c = getchar()) != EOF)
            putchar(c), fputs("writing", stderr);
    }
}

Sie arbeiten gut, weil sie blockieren und nicht beenden auf EOF, aber es ist nicht ganz hat das Problem noch nicht gelöst. Im Moment unter Verwendung eines, die anderen oder beiden Werken in der Theorie, aber in der Praxis zenity zeigt gar nichts jetzt.

Fix Versuch 2

@mvds schlug vor, dass eine reguläre Datei, in Kombination mit tail -f statt cat, kann dies zu tun. Überrascht bei solchen einfachen Lösung (Danke!) Ich habe es versucht, aber leider nur die erste Zeile zeigte sonst in zenity und nichts auf.

Fix Versuch 3

Nach einigem strace'ing tun und git Quellcode Inspektion, merke ich, dass git Ausgaben all ihre Fortschrittsinformationen (etwas über die „Initialized“ -Meldung) auf stderr, und die Tatsache, dass dies die erste Zeile und meine Vermutung, dass es wegen der Katze früh EOF Aufhören war ein Zufall / irrige Annahme (git nicht EOF bis Programmende).

Die Situation schien viel einfacher geworden, da ich nicht zu ändern nichts von dem ursprünglichen Code (zu Beginn der Frage) haben sollte und es sollte funktionieren. Mysteriously jedoch die stderr-Ausgabe ‚verschwindet‘, wenn umgeleitet -. Und das ist nur etwas, das in git geschieht

Testfall? Versuchen Sie dieses, und sehen Sie, wenn Sie etwas in der Datei sehen (Sie werden nicht):

git clone git://anongit.freedesktop.org/xorg/proto/dri2proto 2> hurr

Das geht gegen alles, was ich über stderr und Umleitung wissen; Ich habe sogar ein kleines C-Programm geschrieben, dass Ausgänge auf stderr und stdout zu mir selbst zu beweisen, dass die Umleitung nur nicht funktioniert für git.

Fix Versuch 4

Im Einklang mit Jakub Narebski Antwort, sowie Antworten auf E-Mails ich zur git Mailingliste geschickt, --progress ist die Option, die ich brauche. Beachten Sie, dass diese Option nur nach dem Befehl funktioniert, und nicht vor clone.

Erfolg!

Vielen Dank für Ihre Hilfe. Dies ist die feste Linie:

git clone "$1" "$target" --progress > /tmp/githandler-fifo 2>&1 &

War es hilfreich?

Lösung

Ich denke, dass zumindest einige der Fortschrittsberichte zum Schweigen gebracht werden, wenn der Ausgang ist kein Terminal (tty). Ich bin mir nicht sicher, ob es für Ihren Fall gilt, sondern versuchen, passieren --progress Option 'git clone' (das heißt Verwendung git clone --progress <repository>).

Obwohl ich weiß nicht, ob es das, was Sie haben wollten.

Andere Tipps

Für eine Sache, die die Umleitung der Ausgabe wird analysiert, von rechts nach links, so

git clone "$1" "$target" 2>&1 > /tmp/githandler-fifo &

ist gleich nicht zu

git clone "$1" "$target" > /tmp/githandler-fifo 2>&1 &

Diese wird stderr nach stdout umleiten und dann stdout (einschließlich stderr) in die Datei. Erstere wird stdout in die Datei umleiten, und dann stderr auf stdout zeigen.

Wie zu zenity Rohrleitungen (was ich weiß es nicht), ich glaube, Sie Dinge übermäßig mit dem Named Pipes kompliziert machen können. kann etwas Licht strace verwenden auf die inneren Abläufe der Prozesse sind Sie Anheizen. Für die unerfahrenen, Named Pipes alles noch schlimmer macht im Vergleich zu normalen Rohren.

Da das Experiment mit dem FIFO genannt ‚a‘, ich glaube, das Problem liegt in der Art und Weise zenity verarbeitet seine Eingabe. Was passiert, wenn Sie in zenity von der Tastatur eingeben? (Suspicion: es verhält sich, wie Sie wollen würden, um EOF zu lesen.) Allerdings könnte es, dass zenity Griffe Terminal-Eingang (tty-Eingang) wird regelmäßige Sperrung mit I / O verwendet aber nicht blockierende E / A für alle anderen Gerätetypen. Nicht blockierende I / O ist in Ordnung für die Eingabe von Dateien; es ist weniger wünschenswert für die Eingabe von Rohren oder FIFOs usw. Wenn es dem Einsatz nicht-blockierenden hätte I / O, zenity würde die erste Zeile der Ausgabe erhalten, und dann die Schleife verlassen Denken sie, weil sein zweiten Leseversuch anzeigen würde, getan wurde, dass es gab nichts anderes sofort zur Verfügung.

Aufzeigen, dass das ist, was passiert (oder nicht) wird schwierig sein. Ich würde schauen, um ‚Truss‘ oder ‚strace‘ oder ein anderes System Anrufmonitor zu verfolgen, was zenity tut.

In Bezug auf Abhilfen ... wenn die Hypothese richtig ist, dann müssen Sie zenity davon zu überzeugen, dass es von einem Endgerät und nicht einem FIFO liest, so dass Sie wahrscheinlich auf eine pseudo-tty rig benötigen (oder Pty); der erste Prozess zum Master-Ende des pty schreiben würde und Sie würden arrangieren für zenity vom Slave Ende des pty zu lesen. Sie könnten immer noch den FIFO verwenden -. Obwohl es eine lange Befehlskette macht

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top