Perl 程序用于IPC::Run
通过一系列在运行时确定的命令将文件传递到另一个文件中,就像这个小测试摘录所示:
#!/usr/bin/perl
use IO::File;
use IPC::Run qw(run);
open (my $in, 'test.txt');
my $out = IO::File->new_tmpfile;
my @args = ( [ split / /, shift ], "<", $in); # this code
while ($#ARGV >= 0) { # extracted
push @args, "|", [ split / /, shift ]; # verbatim
} # from the
push @args, ">pipe", $out; # program
print "Running...";
run @args or die "command failed ($?)";
print "Done\n";
它从作为参数给出的命令构建管道,测试文件是硬编码的。问题是如果文件大于 64KiB,管道就会挂起。这是一个cat
在管道中使用以保持简单的演示。首先一个 64KiB(65536 字节)的文件按预期工作:
$ dd if=/dev/urandom of=test.txt bs=1 count=65536
65536 bytes (66 kB, 64 KiB) copied, 0.16437 s, 399 kB/s
$ ./test.pl cat
Running...Done
接下来,再增加一个字节。run
永远不会回来的电话......
$ dd if=/dev/urandom of=test.txt bs=1 count=65537
65537 bytes (66 kB, 64 KiB) copied, 0.151517 s, 433 kB/s
$ ./test.pl cat
Running...
启用后,再加IPCRUNDEBUG
上几只猫,您可以看到它是最后一个没有结束的孩子:
$ IPCRUNDEBUG=basic ./test.pl cat cat cat cat
Running...
...
IPC::Run 0000 [#1(3543608)]: kid 1 (3543609) exited
IPC::Run 0000 [#1(3543608)]: 3543609 returned 0
IPC::Run 0000 [#1(3543608)]: kid 2 (3543610) exited
IPC::Run 0000 [#1(3543608)]: 3543610 returned 0
IPC::Run 0000 [#1(3543608)]: kid 3 (3543611) exited
IPC::Run 0000 [#1(3543608)]: 3543611 returned 0
(对于 64KiB 以下的文件,您会看到所有四个都正常退出)
如何使它适用于任何大小的文件?
(Perl 5,版本 30,subversion 3 (v5.30.3) 为 x86_64-linux-thread-multi 构建,在目标平台 Alpine Linux 和 Arch Linux 上尝试排除 Alpine 的原因)