如何在Perl 6中从绑定管道读取Proc::Async的输出?
解决Proc::Async绑定stdout后无法打印输出的问题
这个错误提示已经说得很明确了:你不能同时把stdout绑定到一个句柄,又通过Supply获取stdout的输出——因为外部程序的标准输出只能有一个流向,要么直接写到你指定的文件句柄,要么通过Supply传递给你的代码,二者不可兼得。下面给你两种不同需求下的解决方案:
需求1:同时将输出保存到文件并实时打印到终端
这种情况不要用bind-stdout,而是通过tap监听stdout的Supply,在回调里同时处理文件写入和终端打印:
my $p = Proc::Async.new("ls", :out); my $h = "ls.out".IO.open(:w); # 监听stdout流,同时处理写入文件和打印 $p.stdout.tap( -> $chunk { $h.print($chunk); print $chunk; }, # 流结束时关闭文件句柄 done => { $h.close; say "输出已保存到ls.out" } ); await $p.start; say "Done";
需求2:先将输出保存到文件,事后再读取打印
如果不需要实时打印,只是想在程序执行完后查看输出,那可以在await完成后直接读取你绑定的文件:
my $p = Proc::Async.new("ls", :out); my $h = "ls.out".IO.open(:w); $p.bind-stdout($h); await $p.start; $h.close; # 必须关闭句柄,确保所有输出都写入文件 # 读取并打印文件内容 say "程序输出:"; say slurp "ls.out"; say "Done";
补充说明
Proc::Async的bind-stdout是底层的重定向操作,它会让外部程序的stdout直接对接你提供的IO句柄,跳过了Perl 6的Supply流机制;而tap是基于Supply来捕获输出,所以两者本质上是互斥的。根据你的实际需求选择对应的方式就可以啦。
内容的提问来源于stack exchange,提问作者jjmerelo
相关产品推荐
相关产品推荐

