我正在写一个图形化的URI处理程序的git://使用bash和zenity链接,我使用的是zenity“文本信息”对话框,显示Git的克隆输出,而它的运行,使用FIFO管道。剧本是大约90线长,所以我不会打扰张贴在这里,但这里是最重要的行:

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

我使用的,而不是直接管FIFO以允许它们异步运行,并允许用于如果关闭zenity窗口杀死GIT中。

问题是,唯一的线,从GIT中的输出出现是第一个:

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

在其它线与计数对象等不显示或显示在终端上。

当前原因

<德尔>,为什么这是行不通的目前的共识似乎是cat是非阻塞和第一行之后退出,只传递一个到zenity而不是休息。我的目标是迫使阻塞的读取,并且有zenity的文本信息对话框显示所有输出渐进。

git输出进度消息在stderr(除“初始化”的消息的任何东西),但目前我尝试管错误输出到文件或与标准输出合并,消息消失。

<强>修复尝试1

我试着写在C,面包和BWRITE猫的功能,两个阻塞的版本,像这样的:

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

他们的工作很好,因为他们阻止,不上EOF退出,但还没有完全解决了这个问题。目前,使用一个,另一个,或两者在理论上的作品,但在实践中,zenity节目什么都没有了。

<强>修复尝试2

@mvds建议使用一个普通的文件,在具有tail -f而非cat组合可以做到这一点。在这样一个简单的解决方案感到惊讶(谢谢!)我尝试过,但遗憾的是,只有第一线zenity,没有别的出现了。

<强>修复尝试3

做一些strace'ing和检查Git的源代码后,我才知道的git输出都在标准错误的进度信息(什么过去的“初始化”的消息),而事实上,这是第一行,我的假设,它是由于猫早期EOF戒烟是一个巧合/误导假设(GIT中没有EOF直到程序结束)。

在局势似乎变得简单了很多,因为我不应该有任何改变,从原来的代码(在这个问题的开始),它应该工作。神秘,然而,stderr输出“消失”重定向时 - 而这仅是这种情况发生在GIT中的东西

测试情况?试试这个,看看你是否在文件中看到什么(你不会):

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

这违背了我所了解的标准错误和重定向一切;我甚至写了一个小C程序的标准错误和标准输出输出来证明自己,重定向只是并不为git的工作。

<强>修复尝试4

在用的JakubNarębski的回答线,以及回复的邮件我发到git的邮件列表,--progress是选择我需要的。请注意,此选项仅在命令之后,而不是之前clone

成功!

非常感谢你的一切帮助。这是固定的行:

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

有帮助吗?

解决方案

我认为,至少一些进展报告被沉默时输出不是终端(TTY)。我不知道它是否适用于你的情况,但试图通过 --progress 选项为“git的克隆”(即使用git clone --progress <repository>)。

虽然我不知道这是否是你想拥有的。

其他提示

一方面,输出重定向被解析从右到左,那么

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

不等于

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

后者将标准错误重定向到标准输出,然后标准输出(包括标准错误)到该文件。前者将标准输出重定向到该文件,并且然后显示在stdout stderr中。

至于管道传输到zenity(我不知道),我想你可能使事情命名管道过于复杂。使用strace可以揭示你射击了过程的内部工作的一些情况。对于经验不足的,命名管道使事情更糟相比正常管道。

由于实验与FIFO称为“A”,我认为问题出在方法zenity处理输入。如果你从键盘输入到zenity会发生什么?使用常规的阻塞I / O,但使用非阻塞I / O的所有其它设备类型:(怀疑它的行为你会想,阅读EOF)。然而,它可能是zenity把手端子输入(TTY输入)。非阻塞I / O是罚款从文件中输入;它是从管道或FIFO等等输入不太理想的。如果它没有使用非阻塞I / O,zenity会得到输出的第一行,然后退出循环认为它做是因为它的第二次读取尝试将表明,没有别的即将上市。

证明这是正在发生的事情(或不)将是非常棘手。我要寻找到“桁架”或“strace的”或其他系统调用监控来跟踪zenity正在做什么。

至于解决方法......如果假设是正确的,那么你就需要说服zenity它从一个终端,而不是一个FIFO读,所以你可能需要时间来搭起一个伪终端(或PTY);第一个进程将写入pty的主端与你安排zenity从pty的从属端读取。你可能仍然使用FIFO太多 - 尽管它使命令的长链

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top