perl如何将perl脚本的列表形式系统调用的STDOUT附加到文件中 [英] perl how can I append STDOUT of list form system call of perl script to a file

查看:102
本文介绍了perl如何将perl脚本的列表形式系统调用的STDOUT附加到文件中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 bosswrap.pl 会生成任意包含空格的数组。它通过系统调用反复发送数组到 wrapped.pl ,后者基于该数组创建STDOUT。

My bosswrap.pl will generate arbitrary arrays containing whitespace in the elements. It repeatedly sends the array by a system call to wrapped.pl, which creates STDOUT based on the array.

随后, bosswrap.pl 必须附加 wrapped.pl bosswrap.pl 控制的文件。那就是我被困住的地方。首先 wrapped.pl

Subsequently, bosswrap.pl must append the STDOUT of wrapped.pl to a file which bosswrap.pl controls. That is where I am stuck. First wrapped.pl:

#!/usr/bin/perl
use strict; use warnings;
print "inside $0\n";
my $countarrayelements=0;
for my $item ( @ARGV ) {
        $countarrayelements++;
        print "$countarrayelements: |$item|\n"; 
    }

然后 bosswrap.pl

#!/usr/bin/perl
use strict; use warnings; 
my $fileresult = "trash.txt";
unlink $fileresult; # rm any existing file
my $handlefileresult; 
my @array = ( 5, "don't you . . . ", "\x09\x21", "\x3f  \x21" );
my $count=0;
print "inside $0\n";
for my $element ( @array ) {
    $count++;
    print "$count\t|$element|\n";
}

#https://stackoverflow.com/questions/50553031/calling-a-shell-command-with-multiple-arguments
#list form: command line arguments pass verbatim, avoid shell interpolation  
system("wrapped.pl", @array) == 0 or die "system failed: \$? = $?";

#This block sends the return code, not the STDOUT, to handlefileresult
open( $handlefileresult, ">> ", $fileresult) || die "$0: can't open $fileresult for appending$!";
print $handlefileresult "not a system call\n";
print {$handlefileresult} system("wrapped.pl", @array) == 0 or die "system failed: \$? = $?";
close ( $handlefileresult ) || die;

#In the following block, select unfortunately will not redirect output of system call:
open( $handlefileresult, ">> ", $fileresult) || die "$0: can't open $fileresult for appending$!";
select $handlefileresult; 
print "selected; BEFORE system call\n";
system("wrapped.pl", @array) == 0 or die "system failed: \$? = $?";
print "selected; AFTER system call\n";
close ( $handlefileresult ) || die;

再次,我想重复调用 wrapped.pl bosswrap.pl 内部,并将这些系统调用的输出放入 $ fileresult

Again, I want to repeatedly call wrapped.pl from inside bosswrap.pl and put the output of these system calls into $fileresult.

@ikegami的一个回复建议使用IPC :: Run qw(run); ,但这会引发错误。我在macOS上运行perl。要使它正常工作,必须做些什么?

One reply @ikegami suggested use IPC::Run qw( run ); but that throws an error. I run perl on macos. What has to be done to get this to work?

> perl --version

This is perl 5, version 18, subversion 4 (v5.18.4) built for darwin-thread-multi-2level
(with 2 registered patches, see perl -V for more detail)

Copyright 1987-2013, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

> bosswrap.pl
Can't locate IPC/Run.pm in @INC (you may need to install the IPC::Run module) (@INC contains: /sw/lib/perl5/darwin-thread-multi-2level /sw/lib/perl5 /sw/lib/perl5/darwin /Library/Perl/5.18/darwin-thread-multi-2level /Library/Perl/5.18 /Network/Library/Perl/5.18/darwin-thread-multi-2level /Network/Library/Perl/5.18 /Library/Perl/Updates/5.18.4 /System/Library/Perl/5.18/darwin-thread-multi-2level /System/Library/Perl/5.18 /System/Library/Perl/Extras/5.18/darwin-thread-multi-2level /System/Library/Perl/Extras/5.18 .) at /Users/BNW/u/kh/bin/bosswrap.pl line 3.
BEGIN failed--compilation aborted at /Users/BNW/u/kh/bin/bosswrap.pl line 3.
> 

基于我做到了

Based on What's the easiest way to install a missing Perl module? I did

> cpan IPC::Run
<snip>
Appending installation info to /Users/BNW/perl5/lib/perl5/darwin-thread-multi-2level/perllocal.pod
  TODDR/IPC-Run-20180523.0.tar.gz
  /usr/bin/make install  -- OK 

然后重新启动此MacBook Pro 10.14.6。但是我显然得到了相同的错误:

And then rebooted this MacBook Pro 10.14.6. But I get apparently the same error:

> bosswrap.pl
Can't locate IPC/Run.pm in @INC (you may need to install the IPC::Run module) (@INC contains: /sw/lib/perl5/darwin-thread-multi-2level /sw/lib/perl5 /sw/lib/perl5/darwin /Library/Perl/5.18/darwin-thread-multi-2level /Library/Perl/5.18 /Network/Library/Perl/5.18/darwin-thread-multi-2level /Network/Library/Perl/5.18 /Library/Perl/Updates/5.18.4 /System/Library/Perl/5.18/darwin-thread-multi-2level /System/Library/Perl/5.18 /System/Library/Perl/Extras/5.18/darwin-thread-multi-2level /System/Library/Perl/Extras/5.18 .) at /Users/BNW/u/kh/bin/bosswrap.pl line 3.
BEGIN failed--compilation aborted at /Users/BNW/u/kh/bin/bosswrap.pl line 3.
> 

我该如何解决?

推荐答案

STDOUT 和Perl的默认输出句柄(使用 select 设置)操作系统不知道的特定于变量的变量。执行的程序不会继承这些。它确实继承了父系统的文件描述符,由底层系统处理。

STDOUT and Perl's default output handle (as set using select) are process-specific variables the OS knows nothing of. An executed program does not inherit these. It does inherit the parent's file descriptors, the underlying system handles.

我会让 IPC :: Run IPC:

I would let IPC::Run or IPC::Run3 do the hard work for me.

use IPC::Run qw( run );

run [ "wrapped.pl", @array ],
   '>>', $fileresult;

die("wrapped.pl killed by signal ".( $? & 0x7F )."\n") if $? & 0x7F;
die("wrapped.pl exited with error ".( $? >> 8 )."\n") if $ ?>> 8;

使用低级核心模块 IPC :: Open3

use IPC::Open3 qw( open3 );

open(local *CHILD_STDIN, '<', '/dev/null')
   or die("Can't open \"/dev/null\": $!\n");
open(local *CHILD_STDOUT, '>>', $fileresult)
   or die("Can't append to \"$fileresult\": $!\n");

my $pid = open3('<&CHILD_STDIN', '>&CHILD_STDOUT', '>&STDERR',
   "wrapped.pl", @array);

waitpid($pid, 0);
die("Can't execute wrapped.pl: $!\n") if $? == -1;
die("wrapped.pl killed by signal ".( $? & 0x7F )."\n") if $? & 0x7F;
die("wrapped.pl exited with error ".( $? >> 8 )."\n") if $ ?>> 8;

这篇关于perl如何将perl脚本的列表形式系统调用的STDOUT附加到文件中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆