How do I get the output of an external command in Perl?

后端 未结 7 1418
闹比i
闹比i 2020-12-03 13:45

I want to have output of Windows command-line program (say, powercfg -l) written into a file which is created using Perl and then read the file line by line in

7条回答
  •  不知归路
    2020-12-03 14:23

    Since the OP is running powercfg, s/he are probably capturing the ouput of the external script, so s/he probably won't find this answer terribly useful. This post is primarily is written for other people who find the answers here by searching.

    This answer describes several ways to start command that will run in the background without blocking further execution of your script.

    Take a look at the perlport entry for system. You can use system( 1, 'command line to run'); to spawn a child process and continue your script.

    This is really very handy, but there is one serious caveat that is not documented. If you start more 64 processes in one execution of the script, your attempts to run additional programs will fail.

    I have verified this to be the case with Windows XP and ActivePerl 5.6 and 5.8. I have not tested this with Vista or with Stawberry Perl, or any version of 5.10.

    Here's a one liner you can use to test your perl for this problem:

    C:\>perl -e "for (1..100) { print qq'\n $_\n-------\n'; system( 1, 'echo worked' ), sleep 1 }
    

    If the problem exists on your system, and you will be starting many programs, you can use the Win32::Process module to manage your application startup.

    Here's an example of using Win32::Process:

    use strict;
    use warnings;
    
    use Win32::Process;
    
    if( my $pid = start_foo_bar_baz() ) {
        print "Started with $pid";
    }
    :w
    
    sub start_foo_bar_baz {
    
        my $process_object;  # Call to Create will populate this value.
        my $command = 'C:/foo/bar/baz.exe';  # FULL PATH to executable.
        my $command_line = join ' ',
               'baz',   # Name of executable as would appear on command line
               'arg1',  # other args
               'arg2';
    
        # iflags - controls whether process will inherit parent handles, console, etc.
        my $inherit_flags = DETACHED_PROCESS;  
    
        # cflags - Process creation flags.
        my $creation_flags = NORMAL_PRIORITY_CLASS;
    
        # Path of process working directory
        my $working_directory = 'C:/Foo/Bar';
    
        my $ok = Win32::Process::Create(
           $process_object,
           $command,
           $command_line,
           $inherit_flags,
           $creation_flags, 
           $working_directory,
        );
    
        my $pid;
        if ( $ok ) {
            $pid = $wpc->GetProcessID;
        }
        else {
            warn "Unable to create process: "
                 . Win32::FormatMessage( Win32::GetLastError() ) 
            ;
            return;
        }
    
        return $pid;
    }
    

提交回复
热议问题