有没有办法在并行进程的进程终止时刷新标准输出



我在一台机器上并行运行多个独立程序。 这些进程(比如 100 个(都相对较短(<5 分钟(,它们的输出限制在几百行(~KB(。

通常,终端中的输出会变得混乱,因为进程直接写入同一缓冲区。我希望这些输出是未损坏的,以便更容易调试某些进程。我可以将这些输出写入临时文件,但我想限制磁盘 IO,如果可能的话,我更喜欢另一种方法。它需要清理,并且可能不会真正提高代码的可读性。

是否有任何 shell 本机方法允许缓冲区被 PID 分离,然后在进程终止时刷新到 stdout/stderr?你看到还有其他方法可以做到这一点吗?

更新

我最终使用了@Gem评论中的tail -n 1000000技巧。由于我使用的命令很长并且(覆盖多行(,并且我已经使用了子外壳( ... ) &因此从( ... ) &( ... ) 2>&1 | tail -n 1000000 &的变化非常小。

你可以用GNU Parallel做到这一点。使用-k使输出保持有序,:::分隔要传递给程序的参数。

在这里,我们并行运行 4 个echo实例:

parallel -k echo {} ::: {0..4}
0
1
2
3
4

现在添加--tag,使用您正在使用的文件名或参数标记输出行:

parallel --tag -k 'echo "Line 1, param {}"; echo "Line 2, param {}"' ::: {1..4}
1   Line 1, param 1
1   Line 2, param 1
2   Line 1, param 2
2   Line 2, param 2
3   Line 1, param 3
3   Line 2, param 3
4   Line 1, param 4
4   Line 2, param 4

您应该注意到,每行在左侧都标有参数,并且每个作业中的两行都保持在一起。


现在,您可以指定输出的组织方式。

  • 使用--group按作业对输出进行分组
  • 使用--line-buffer一次缓冲一行
  • 如果您希望输出全部混合,请使用--ungroup,但尽快可用

听起来你只是想要系统日志,或者更确切地说是记录它的 Bash 接口。例:

echo "Something happened!" | logger -i -p local0.notice

如果您坚持要输出stderr,请使用--stderr.rsyslog将处理缓冲、原子写入等,并且可能非常擅长优化磁盘 I/O。但是,您也可以轻松地将 rsyslog 配置为将日志工具(即 local0 或您选择使用的任何内容(路由到您想要的任何位置,例如在 tmpfs 或专用磁盘上,甚至通过 TCP。参见/etc/rsyslog.conf。

相关内容

  • 没有找到相关文章

最新更新