13 Stimmen

git stderr Ausgabe kann nicht weitergeleitet werden

Ich schreibe einen grafischen URI-Handler für git://-Links mit bash und zenity, und ich verwende einen zenity-'text-info'-Dialog, um die Klonausgabe von git anzuzeigen, während es läuft, unter Verwendung von FIFO-Piping. Das Skript ist etwa 90 Zeilen lang, daher werde ich es hier nicht posten, aber hier sind die wichtigsten Zeilen:

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

Ich verwende FIFO statt einer direkten Pipe, damit sie asynchron laufen und Git beendet werden kann, wenn das Zenity-Fenster geschlossen wird.

Das Problem ist, dass die einzige Zeile, die in der Ausgabe von git erscheint, die erste ist:

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

Die anderen Zeilen mit Zählobjekten usw. erscheinen nicht oder werden auf dem Terminal angezeigt.

Aktueller Grund

Der derzeitige Konsens darüber, warum dies nicht funktioniert, scheint zu sein, dass cat ist nicht blockierend und bricht nach der ersten Zeile ab und übergibt nur diese an zenity und nicht den Rest. Mein Ziel ist es, das Blockieren für das Lesen zu erzwingen und den Textinfodialog von zenity zu haben, der alle Ausgaben nach und nach anzeigt.

git gibt Fortschrittsmeldungen (alles außer der Meldung "Initialisiert") auf stderr aus, aber sobald ich versuche, stderr in eine Datei zu leiten oder mit stdout zusammenzuführen, verschwinden die Meldungen.

Reparaturversuch 1

Ich habe versucht, zwei blockierende Versionen von cat's functions in C zu schreiben, bread und bwrite, wie folgt:

#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 funktionieren gut, weil sie blockieren und nicht bei EOF aufhören, aber das Problem ist damit noch nicht ganz gelöst. Im Moment funktioniert die Verwendung des einen, des anderen oder beider in der Theorie, aber in der Praxis zeigt zenity überhaupt nichts mehr an.

Reparaturversuch 2

@mvds schlug vor, dass die Verwendung einer regulären Datei in Kombination mit tail -f statt cat kann dies tun. Überrascht über eine so einfache Lösung (danke!) Ich habe es versucht, aber leider nur die erste Zeile zeigte sich in zenity und nichts anderes.

Reparaturversuch 3

Nachdem ich etwas strace'ing gemacht und den Quellcode von git inspiziert habe, stelle ich fest, dass git alle seine Fortschrittsinformationen (alles, was über die "Initialized"-Meldung hinausgeht) auf stderr ausgibt, und die Tatsache, dass dies die erste Zeile ist und meine Annahme, dass es daran liegt, dass cat bei EOF vorzeitig beendet wird, war ein Zufall/eine falsche Annahme (git beendet EOF erst, wenn das Programm endet).

Die Situation schien viel einfacher zu werden, da ich nichts an dem ursprünglichen Code (am Anfang der Frage) ändern muss und es funktionieren sollte. Mysteriöserweise "verschwindet" jedoch die stderr-Ausgabe, wenn sie umgeleitet wird - und das ist nur etwas, das in Git passiert.

Testfall? Versuchen Sie dies, und sehen Sie, ob Sie etwas in der Datei sehen (das werden Sie nicht):

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

Das widerspricht allem, was ich über stderr und Umleitung weiß; ich habe sogar ein kleines C-Programm geschrieben, das auf stderr und stdout ausgibt, um mir zu beweisen, dass die Umleitung für Git einfach nicht funktioniert.

Reparaturversuch 4

Im Einklang mit der Antwort von Jakub Narebski und den Antworten auf E-Mails, die ich an die Git-Mailingliste geschickt habe, --progress ist die Option, die ich brauche. Beachten Sie, dass diese Option nur nach dem Befehl funktioniert, und nicht vor clone .

Erfolgreich!

Herzlichen Dank für Ihre Hilfe. Dies ist der Festnetzanschluss:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X