我在一台机器上并行运行多个独立程序。 这些进程(比如 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。