How can I check the status of the first program in pipeline in Perl's system()?

后端 未结 7 629
小蘑菇
小蘑菇 2021-01-21 06:41
perl -e \'system (\"crontab1 -l\");print $?\'

returns -1 as expected (program crontab1 doesn\'t exist)

perl -e \'system (\"crontab1 -l|         


        
7条回答
  •  青春惊慌失措
    2021-01-21 07:09

    [This was composed as an answer to another question which was closed as a duplicate of this one.]

    Executing a shell command requires executing a shell. To that end,

    system($shell_command)
    

    is equivalent to

    system('/bin/sh', '-c', $shell_command)
    

    As such, all of your examples run a single program (/bin/sh). If you want the exit statuses of multiple children, you're going to need to have multiple children!

    use IPC::Open3 qw( open3 );
    
    open(local *CHILD1_STDIN, '<', '/dev/null')
       or die $!;
    
    pipe(local *CHILD2_STDIN, local *CHILD1_STDOUT)
       or die $!;
    
    my $child1_pid = open3(
       '<&CHILD1_STDIN',
       '>&CHILD1_STDOUT',
       '>&STDERR',
       'prog1', 'arg1', 'arg2',
    );
    
    my $child2_pid = open3(
       '<&CHILD2_STDIN',
       '>&STDOUT',
       '>&STDERR',
       'prog2', 'arg1', 'arg2',
    );
    
    my @pipe_status = map { waitpid($_, 0) } $child1_pid, $child2_pid;
    

    IPC::Open3 is rather low level. IPC::Run3 and/or IPC::Run can possibly make this easier. [Update: Indeed, IPC::Run does].

提交回复
热议问题