Domanda

Sto scrivendo un gestore grafico di URI per git: // collegamenti con bash e zenity, e sto usando un 'text-info' dialogo zenity all'uscita clone git show di mentre è in esecuzione, utilizzando FIFO tubazioni. Lo script è di circa 90 righe lungo, quindi non mi dilungherò postarlo qui, ma ecco le linee più importanti:

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

sto usando FIFO al posto di un tubo diretta per consentire loro di eseguire in modo asincrono e permettono per aver ucciso git se la finestra è chiusa zenity.

Il problema è che l'unica linea che appare da uscita di Git è il primo:

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

Le altre linee con oggetti conteggio, ecc non mostrare o sono presenti sul terminale.

motivo corrente

L'attuale consenso sul motivo per cui questo non sta funzionando sembra essere che cat non è bloccante e si chiude dopo la prima riga, solo di passaggio che per zenity e non il resto. Il mio obiettivo è quello di forzare il blocco per la lettura, e hanno informazioni testo di zenity dialogo mostrare tutto l'output progressivamente.

uscite git progresso messaggi (altro che il messaggio "inizializzata") su stderr, ma il momento cerco di stderr pipe in un file o di fondersi con stdout, i messaggi spariscono.

Fix tentativo 1

ho cercato di scrivere due versioni di blocco delle funzioni del gatto in C, pane e bwrite, in questo modo:

#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);
    }
}

Si funziona bene perché bloccano e non smettere l'EOF, ma non ha del tutto risolto il problema ancora. Al momento, utilizzando uno, l'altro o entrambi, opere in teoria, ma in pratica, spettacoli Zenity nulla ora.

Fix tentativo 2

@mvds ha suggerito che l'utilizzo di un file normale, in combinazione con tail -f piuttosto che cat, può fare questo. Sorpreso a tale soluzione semplice (grazie!) Ho provato ma purtroppo, solo la prima riga si presentò in zenity e nient'altro.

Fix tentativo 3

Dopo aver fatto qualche strace'ing e ispezionare il codice sorgente di git, mi rendo conto che git uscite tutte le sue informazioni di avanzamento (nulla oltre il messaggio "inizializzata") su stderr, e il fatto che questa è la prima linea e la mia ipotesi che è a causa del gatto smettere presto EOF è stata una coincidenza / ipotesi fuorviante (git non lo fa EOF fino alla fine del programma).

La situazione sembrava diventare molto più semplice, come non avrei dovuto cambiare nulla dal codice originale (all'inizio della questione) e dovrebbe funzionare. Misteriosamente, però, l'uscita stderr 'svanisce', quando reindirizzato -. E questo è solo qualcosa che accade in git

caso

Prova? Prova questo, e vedere se si vede nulla nel file (non si vuole):

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

Questo va contro tutto quello che so su stderr e il reindirizzamento; Ho anche scritto un piccolo programma C che uscite su stderr e stdout per dimostrare a me stesso che il reindirizzamento non solo lavoro per git.

Fix tentativo 4

In linea con la risposta di Jakub Narębski, così come le risposte alle e-mail che ho inviato alla mailing list git, --progress è la necessità opzione che ho. Si noti che questa opzione funziona solo dopo il comando, e non prima clone.

Successo!

Grazie mille per il vostro aiuto. Questa è la linea fissa:

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

È stato utile?

Soluzione

Credo che almeno alcune delle relazioni ottiene tacere quando l'uscita è non un terminale (tty). Non sono sicuro se si applica al vostro caso, ma cerco di trasmettere --progress per 'clone git' (vale a dire l'uso git clone --progress <repository>).

Anche se non so se è quello che si voleva avere.

Altri suggerimenti

Per prima cosa, il reindirizzamento di uscita viene analizzato da destra a sinistra, in modo da

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

non è uguale a

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

Quest'ultimo reindirizza stderr su stdout, e poi stdout (compresi stderr) al file. L'ex reindirizzerà stdout al file, e poi mostrare stderr su stdout.

Per quanto riguarda la connessione all'attacco zenity (che non conosco), penso che potrebbe essere fare le cose troppo complicate con la named pipe. Utilizzando strace può far luce sul funzionamento interno dei processi che si stanno sparando in su. Per gli inesperti, named pipe rendere le cose peggiori rispetto ai tubi normali.

Dato l'esperimento con il FIFO chiamato 'a', credo che le bugie problema nel modo zenity elabora il suo input. Che cosa succede se si digita in zenity dalla tastiera? (Sospetto: si comporta come ci si desidera, a leggere per EOF.) Tuttavia, potrebbe essere che le maniglie Zenity ingresso del terminale (ingresso TTY) utilizzando il blocco normale I / O, ma usi non-blocking I / O per tutti gli altri tipi di dispositivi. Non bloccante I / O va bene per l'input da file; è meno desiderabile per l'ingresso da tubi o FIFO, ecc Se lo ha fatto uso non-blocking I / O, zenity otterrebbe la prima riga di output, e quindi uscire dal ciclo pensando che fosse fatto perché il suo tentativo secondo in lettura indicherebbe che non c'era nient'altro immediatamente disponibili.

dimostrando che questo è ciò che sta accadendo (o non) sarà difficile. Sarei cercando di 'capriata' o 'strace' o un altro monitor chiamata di sistema per monitorare ciò che sta facendo zenity.

Per quanto riguarda soluzioni alternative ... se l'ipotesi è corretta, allora avrete bisogno di convincere zenity che sta leggendo da un terminale e non una FIFO, quindi avrete probabilmente bisogno di mettere su una pseudo-tty (o pty); il primo processo avrebbe scritto alla fine padrone del PTY e si sarebbe organizzare per zenity di leggere la fine schiavo del PTY. Si potrebbe continuare a utilizzare il FIFO troppo -. Se si fa una lunga catena di comando

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top