bash – 后台作业的乱码输出
我试图逐行收集bash脚本中几个子进程的输出,以便将它转发到另一个进程.
我发现没有任何东西可以保证子过程的输出不会混合,但对我来说每条输出线都适当地输出到输出是很重要的.输出之间的顺序无关紧要. 这是混合/乱码输出的示例: #!/bin/bash for i in {1..1000}; do ( { echo BEGIN; dmesg; echo END; } | tr -d 'n'; echo ) & done wait 运行这个: $./test_output.sh | perl -ne 'print "$1n" if m/(.{1,20}BEGIN.{0,20})/' | head 0.000000] SRAT: PXMBEGIN[ 0.000000] Initi ME through PCIe PME BEGIN[ 0.000000] Initi ME through PCIe PME BEGIN[ 0.000000] Initi [ 0.209816] pci 0BEGIN[ 0.000000] Initi ciehp 0000:00:16.1:pBEGIN[ 0.000000] Initi CI: Updating contextBEGIN[ 0.000000] Initi l family 2[ 0.588BEGIN[ 0.000000] Initi ME through PCIe PME BEGIN[ 0.000000] Initi CI: Updating contextBEGIN[ 0.000000] Initi 3922 pages,LIFO batBEGIN[ 0.000000] Initi 你可以看到混合内容的几行. 当然,没有&一切都好. 所以现在,我别无选择,只能将每个孩子的输出重定向到一个文件,然后经过一个大的等待,将所有这些文件都捕获. 使用GNU parallel运行相同的工作是部分工作,但它不是我环境中的一个选项.
因此,GNU parallel将在每个作业完成后立即写入每个作业输出,并且它负责不混合输出.非常好.但我也有兴趣尽快获得每份工作的输出,即不等待工作退出.有“-u”开关,但它会混合作业输出. 我是否需要使用fifo,选择甚至编写perl脚本? – 我想我已经找到了为什么/如何/何时输出混合在man 7管道中
解决方法
这是我的第一次抽奖.这是一个简单的脚本,可以在后台启动stdin上给出的所有命令(不确定这是我想要的)并逐行收集这些命令.
#!/usr/bin/env perl use strict; use warnings; use IO::Select; use POSIX qw(strftime); my $SELECT_TIMEOUT = 1; my $TAG_SEPARATOR = '|'; my $TAG_TIMESTAMP_FORMAT = '%Y-%m-%dT%H:%M:%S'; sub multiplex { my @commands = @_; my %tags = (); # fd -> cmd my $sel = IO::Select->new(); for my $cmd (@commands) { $cmd =~ s/^s+|s+$//g; my $fd; if (!open($fd,"-|",$cmd)) { warn "Cannot start '$cmd': $!"; next; } else { $tags{$fd} = $cmd; $sel->add($fd); } } while ($sel->handles > 0) { my @handles = $sel->can_read($SELECT_TIMEOUT); # maybe something went wrong if (!@handles) { for my $fd ($sel->has_exception($SELECT_TIMEOUT)) { $sel->remove($fd); } next; } my $now = strftime($TAG_TIMESTAMP_FORMAT,localtime(time())); for my $fd (@handles) { if (defined(my $line = <$fd>)) { if ($TAG_SEPARATOR) { $line = join($TAG_SEPARATOR,$now,$tags{$fd},$line); } print $line; } else { # EOF $sel->remove($fd); } } } } multiplex(<STDIN>); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |