我有一个调用两个命令的脚本:
long_running_command | print_progress
Run Code Online (Sandbox Code Playgroud)
在long_running_command打印的进展,但我很不满意它。我正在使用print_progress使其更好(即,我在一行中打印进度)。
问题:将管道连接到标准输出也会激活一个 4K 缓冲区,所以漂亮的打印程序什么都没有……什么都没有……什么都没有……很多……:)
如何禁用4K缓冲区long_running_command(不,我没有源)?
我如何使用 BASH 魔法来实现这一目标?
我只想在屏幕上看到 stderr 输出,
但我希望将 stdout 和 stderr 都写入文件。
澄清:我希望 stdout 和 stderr 最终出现在同一个文件中。按照它们发生的顺序。
不幸的是,下面的答案都没有做到这一点。
让我详细描述一下这个问题:
我运行一些无人值守的脚本,这些脚本可以生成标准输出和标准错误行,我想按照终端模拟器显示的精确顺序捕获它们,然后向它们添加前缀,如“STDERR:”和“STDOUT:”。
我曾尝试对它们使用管道甚至基于 epoll 的方法,但无济于事。我认为解决方案是在 pty 使用中,尽管我不是这方面的高手。我还查看了Gnome 的 VTE的源代码,但这并没有多大成效。
理想情况下,我会使用Go而不是 Bash 来完成此操作,但我无法做到。由于缓冲,管道似乎自动禁止保持正确的行顺序。
有人能做类似的事情吗?或者这是不可能的?我认为,如果终端模拟器可以做到,那么它就不是——也许通过创建一个以不同方式处理 PTY 的小型 C 程序?
理想情况下,我会使用异步输入来读取这 2 个流(STDOUT 和 STDERR),然后根据我的需要重新打印它们,但输入顺序至关重要!
注意:我知道stderred但它不适用于 Bash 脚本,并且无法轻松编辑以添加前缀(因为它基本上包含了大量系统调用)。
更新:在两个要点下面添加
(可以在我提供的示例脚本中添加亚秒随机延迟,以证明结果一致)
更新:正如@Gilles 指出的那样,这个问题的解决方案也将解决另一个问题。但是,我得出的结论是,不可能在这里和那里做所要求的事情。当使用2>&1两个流在 pty/pipe 级别正确合并时,但要单独使用流并以正确的顺序使用,确实应该使用涉及系统调用挂钩的stderred方法,并且可以在许多方面被视为脏。
如果有人可以反驳上述内容,我将渴望更新这个问题。