http://www.perlmonks.org?node_id=274975


in reply to Re: Re: Re: Use of IPC::Run rather than system()
in thread Use of IPC::Run rather than system()

For STDIN/-ERR, just print the output to the appropriate handles yourself. For STDIN, if you have taken control of the subprocesses STDIN yourself, just copy the user input in there yourself. You can do that "realtime" rather than post mortem by passing closures rather scalar refs, if memory serves.

Makeshifts last the longest.

  • Comment on Re^4: Use of IPC::Run rather than system()

Replies are listed 'Best First'.
Re: Re^4: Use of IPC::Run rather than system()
by IlyaM (Parson) on Jul 16, 2003 at 19:18 UTC
    Something like this should work:
    use IPC::Run qw(run); my ($out, $err) = ('', ''); run(['/path/to/prog', @args], '>', sub { $out .= $_[0]; print $_[0] }, '2>', sub { $err .= $_[0]; print $_[0] });

    --
    Ilya Martynov, ilya@iponweb.net
    CTO IPonWEB (UK) Ltd
    Quality Perl Programming and Unix Support UK managed @ offshore prices - http://www.iponweb.net
    Personal website - http://martynov.org

      This seems to have worked the best of all, after I turned off buffering for STDOUT/STDERR, with code such as this:

      my ($ofh) = select(STDOUT); $| = 1; select($ofh); $ofh = select(STDERR); $| = 1; select($ofh); my ($out, $err); run ( [ '/usr/sbin/pkgrm', 'VRTSvxvm' ], '>', sub { $out .= $_[0]; print $_[0] }, '2>', sub { $err .= $_[0]; print $_[0] }, );

      Now, if the program I was running demands that it connects to a pty before it will unbuffer STDOUT/STDERR properly, what could I do? I've tried the following, but it doesn't send any output to the screen:

      use IPC::Run qw(run); my ($out, $err); run ( [ '/usr/sbin/pkgrm', 'VRTSvxvm' ], '>', sub { $out .= $_[0]; print $_[0] }, '>', '>pty>', '2>', sub { $err .= $_[0]; print $_[0] }, '2>', '>pty>' );

        I'm not sure it is correct syntax. From IPC::Run docs:

        '>pty>' means '&>pty>', not '1>pty>' The pseudo terminal redirects both stdout and stderr unless you specify a file descriptor. If you want to grab stderr separately, do this: start \@cmd, '<pty<', \$in, '>pty>', \$out, '2>', \$err +;

        So probably your code should look like (untested):

        use IPC::Run qw(run); my ($out, $err); run ( [ '/usr/sbin/pkgrm', 'VRTSvxvm' ], '>pty>', sub { $out .= $_[0]; print STDOUT $_[0] }, '2>', sub { $err .= $_[0]; print STDERR $_[0] }, );

        --
        Ilya Martynov, ilya@iponweb.net
        CTO IPonWEB (UK) Ltd
        Quality Perl Programming and Unix Support UK managed @ offshore prices - http://www.iponweb.net
        Personal website - http://martynov.org