Escribo un controlador URI gráfico para git: // enlaces con bash y zenity, y estoy usando un cuadro de diálogo zenity 'text-info' para mostrar la salida de clonación de git mientras se ejecuta , utilizando tuberías FIFO. El guión es de aproximadamente 90 líneas de largo, por lo que no se molestará en publicar aquí, pero aquí es las líneas más importantes:git stderr output no pipe
git clone "$1" "$target" 2>&1 | cat >> /tmp/githandler-fifo &
cat /tmp/githandler-fifo | zenity --text-info --text='Cloning git repository' &
que estoy usando FIFO en lugar de una tubería directa para permitir que se ejecuten de forma asincrónica y permiten por matar a git si la ventana de zenity está cerrada.
El problema es que la única línea que aparece a partir de la salida de Git es el primero:
Initialized empty Git repository in /home/delan/a/.git/
Las otras líneas con contar objetos, etc. no muestran o se muestran en el terminal.
razón actual
El consenso actual de por qué esto no está funcionando parece ser que cat
es no bloqueante y se cierra después de la primera línea, sólo el paso, que a Zenity y no el resto. Mi objetivo es forzar el bloqueo de la lectura y hacer que el cuadro de diálogo de texto de zenity muestre todos los resultados de forma progresiva.
git
salidas de mensajes de progreso (que no sea el mensaje "iniciada" nada) en stderr, pero en el momento que intento stderr tubería a un archivo o fusionarse con la salida estándar, los mensajes desaparecen.
intento Fix 1
He tratado de escribir dos versiones de bloqueo de funciones de gato en C, pan y bwrite, así:
#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);
}
}
Ellos trabajan muy bien porque bloquean y don 'Salir en EOF, pero aún no ha resuelto el problema. Por el momento, usar uno, el otro o ambos funciona en teoría, pero en la práctica, el zenity no muestra nada ahora.
intento Fix 2
@mvds sugirieron que el uso de un archivo normal, en combinación con tail -f
en lugar de cat
, puede hacer esto. Sorprendido por una solución tan simple (¡gracias!) Lo intenté, pero desafortunadamente, solo la primera línea apareció en zenity y nada más.
intento Fix 3
Después de hacer algunas strace'ing e inspeccionar el código fuente de Git, que se dan cuenta de que las salidas git toda su información de progreso (cualquier cosa más allá del mensaje "iniciada") en stderr, y el hecho de que esta es la primera línea y mi suposición de que es debido a que el gato dejó de fumar temprano en EOF fue una suposición de coincidencia/equivocada (git no EOF hasta que finaliza el programa).
La situación parecía ser mucho más simple, ya que no debería tener que cambiar nada del código original (al comienzo de la pregunta) y debería funcionar. Misteriosamente, sin embargo, la salida stderr 'desaparece' cuando se redirige, y esto es solo algo que sucede en git.
¿Estuche de prueba?Prueba de esto, y ver si ves algo en el archivo (que no lo hará):
git clone git://anongit.freedesktop.org/xorg/proto/dri2proto 2> hurr
Esto va en contra de todo lo que sé sobre stderr y la redirección; Incluso he escrito un pequeño programa de C que da salida en stderr y stdout para probarme a mí mismo que la redirección simplemente no funciona para git.
intento Fix 4
De acuerdo con la respuesta de Jakub Narębski, así como las respuestas a mensajes de correo electrónico que he enviado a la lista de correo de git, --progress
es la opción que necesito. Tenga en cuenta que esta opción solo funciona después del comando, y no antes de clone
.
¡Éxito!
Muchas gracias por toda su ayuda. Esta es la línea fija:
git clone "$1" "$target" --progress > /tmp/githandler-fifo 2>&1 &
Dios mío ... me has salvado la vida .... ha tenido el mismo problema – KnF
¡Éxito! Gracias por eso. --progreso fue la pieza que faltaba del rompecabezas para mí. – Form