有没有一种方法可以在并行进程终止时刷新标准输出

时间:2018-08-16 09:14:16

标签: bash shell parallel-processing multiprocessing flush

我正在同一台计算机上并行运行多个独立程序。 这些过程(例如100个)都相对较短(<5分钟),其输出限制为几百行(约千字节)。

通常,终端中的输出随后会被破坏,因为进程直接写入同一缓冲区。我希望这些输出是正确的,以便调试某些进程更加容易。我可以将这些输出写入临时文件,但我想限制磁盘IO,并且在可能的情况下希望使用其他方法。这将需要清理,并且可能不会真正提高代码的可读性。

是否有任何Shell本机方法可以将缓冲区进行PID分离,然后在进程终止时刷新到stdout / stderr?您看到其他方法吗?

更新

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

2 个答案:

答案 0 :(得分:2)

您可以使用 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,但要尽快使用

答案 1 :(得分:1)

听起来像您只想要syslog,或者更像是logger的Bash界面。示例:

$(document).ready(function() {
  console.log('Ready');
  $('a.nav-link').unbind('click').bind('click', function(e) {});
});

如果您坚持要也输出到stderr ,请使用echo "Something happened!" | logger -i -p local0.notice --stderr将处理缓冲,原子写入等,并且大概在优化磁盘I / O方面非常出色。但是,您也可以轻松配置rsyslog以将日志工具(即local0或您选择使用的工具)路由到所需的任何位置,例如在tmpfs或专用磁盘上,甚至通过TCP。参见/etc/rsyslog.conf