IPC-Run
view release on metacpan or search on metacpan
lib/IPC/Run.pm view on Meta::CPAN
$h = start \@cat, $in, '>pipe', \*OUT, '2>pipe', \*ERR;
$in = "hello world\n";
finish $h;
print <OUT>;
print <ERR>;
close OUT;
close ERR;
causes two pipe to be created, with one end attached to cat's stdout
and stderr, respectively, and the other left open on OUT and ERR, so
that the script can manually
read(), select(), etc. on them. This is like
the behavior of IPC::Open2 and IPC::Open3.
B<Win32>: The handle returned is actually a socket handle, so you can
use select() on it.
=item Duplicating output descriptors: >&m, n>&m
This duplicates output descriptor number n (default is 1 if n is omitted)
from descriptor number m.
=item Duplicating input descriptors: <&m, n<&m
This duplicates input descriptor number n (default is 0 if n is omitted)
from descriptor number m
=item Closing descriptors: <&-, 3<&-
This closes descriptor number n (default is 0 if n is omitted). The
following commands are equivalent:
run \@cmd, \undef;
run \@cmd, '<&-';
run \@cmd, '<in.txt', '<&-';
Doing
run \@cmd, \$in, '<&-'; ## SIGPIPE recipe.
is dangerous: the parent will get a SIGPIPE if $in is not empty.
=item Redirecting both stdout and stderr: &>, >&, &>pipe, >pipe&
The following pairs of commands are equivalent:
run \@cmd, '>&', \$out; run \@cmd, '>', \$out, '2>&1';
run \@cmd, '>&', 'out.txt'; run \@cmd, '>', 'out.txt', '2>&1';
etc.
File descriptor numbers are not permitted to the left or the right of
these operators, and the '&' may occur on either end of the operator.
The '&>pipe' and '>pipe&' variants behave like the '>pipe' operator, except
that both stdout and stderr write to the created pipe.
=item Redirection Filters
Both input redirections and output redirections that use scalars or
subs as endpoints may have an arbitrary number of filter subs placed
between them and the child process. This is useful if you want to
receive output in chunks, or if you want to massage each chunk of
data sent to the child. To use this feature, you must use operator
syntax:
run(
\@cmd
'<', \&in_filter_2, \&in_filter_1, $in,
'>', \&out_filter_1, \&in_filter_2, $out,
);
This capability is not provided for IO handles or named files.
Two filters are provided by IPC::Run: appender and chunker. Because
these may take an argument, you need to use the constructor functions
new_appender() and new_chunker() rather than using \& syntax:
run(
\@cmd
'<', new_appender( "\n" ), $in,
'>', new_chunker, $out,
);
=back
=head2 Just doing I/O
If you just want to do I/O to a handle or file you open yourself, you
may specify a filehandle or filename instead of a command in the harness
specification:
run io( "filename", '>', \$recv );
$h = start io( $io, '>', \$recv );
$h = harness \@cmd, '&', io( "file", '<', \$send );
=head2 Options
Options are passed in as name/value pairs:
run \@cat, \$in, debug => 1;
If you pass the debug option, you may want to pass it in first, so you
can see what parsing is going on:
run debug => 1, \@cat, \$in;
=over
=item debug
Enables debugging output in parent and child. Debugging info is emitted
to the STDERR that was present when IPC::Run was first C<use()>ed (it's
C<dup()>ed out of the way so that it can be redirected in children without
having debugging output emitted on it).
=back
=head1 RETURN VALUES
lib/IPC/Run.pm view on Meta::CPAN
in the corresponding position.
=cut
sub full_paths {
my IPC::Run $self = shift;
return map { $_->{PATH} } @{ $self->{KIDS} };
}
=pod
=item finished
$h->finished;
Returns true if the harness has been started and all child processes have
finished (i.e. C<finish> has been called or the harness has run to
completion). Returns false otherwise, including when the harness has not
yet been started.
Unlike L</result> and L</full_result>, C<finished> does not throw an
exception when the harness has not yet run -- it simply returns false.
This makes it safe to call at any point to test completion status.
my $h = harness(\@cmd);
$h->start;
# ... do other work, pump $h as needed ...
if ( $h->finished ) {
print "Exit code: ", $h->result(0), "\n";
}
=cut
sub finished {
my IPC::Run $self = $_[0];
return $self->{STATE} == _finished;
}
##
## Filter Scaffolding
##
use vars (
'$filter_op', ## The op running a filter chain right now
'$filter_num', ## Which filter is being run right now.
);
##
## A few filters and filter constructors
##
=pod
=back
=back
=head1 FILTERS
These filters are used to modify input our output between a child
process and a scalar or subroutine endpoint.
=over
=item binary
run \@cmd, ">", binary, \$out;
run \@cmd, ">", binary, \$out; ## Any TRUE value to enable
run \@cmd, ">", binary 0, \$out; ## Any FALSE value to disable
This is a constructor for a "binmode" "filter" that tells IPC::Run to keep
the carriage returns that would ordinarily be edited out for you (binmode
is usually off). This is not a real filter, but an option masquerading as
a filter.
It's not named "binmode" because you're likely to want to call Perl's binmode
in programs that are piping binary data around.
=cut
sub binary(;$) {
my $enable = @_ ? shift : 1;
return bless sub { $enable }, "IPC::Run::binmode_pseudo_filter";
}
=pod
=item new_chunker
This breaks a stream of data in to chunks, based on an optional
scalar or regular expression parameter. The default is the Perl
input record separator in $/, which is a newline be default.
run \@cmd, '>', new_chunker, \&lines_handler;
run \@cmd, '>', new_chunker( "\r\n" ), \&lines_handler;
Because this uses $/ by default, you should always pass in a parameter
if you are worried about other code (modules, etc) modifying $/.
If this filter is last in a filter chain that dumps in to a scalar,
the scalar must be set to '' before a new chunk will be written to it.
As an example of how a filter like this can be written, here's a
chunker that splits on newlines:
sub line_splitter {
my ( $in_ref, $out_ref ) = @_;
return 0 if length $$out_ref;
return input_avail && do {
while (1) {
if ( $$in_ref =~ s/\A(.*?\n)// ) {
$$out_ref .= $1;
return 1;
}
my $hmm = get_more_input;
unless ( defined $hmm ) {
$$out_ref = $$in_ref;
$$in_ref = '';
return length $$out_ref ? 1 : 0;
lib/IPC/Run.pm view on Meta::CPAN
=cut
##
## Filter implementation interface
##
sub get_more_input() {
++$filter_num;
my $r = eval {
confess "get_more_input() called and no more filters in chain"
unless defined $filter_op->{FILTERS}->[$filter_num];
$filter_op->{FILTERS}->[$filter_num]->(
$filter_op->{FBUFS}->[ $filter_num + 1 ],
$filter_op->{FBUFS}->[$filter_num],
); # if defined ${$filter_op->{FBUFS}->[$filter_num+1]};
};
--$filter_num;
die $@ if $@;
return $r;
}
1;
=pod
=back
=head1 TODO
These will be addressed as needed and as time allows.
Stall timeout.
Expose a list of child process objects. When I do this,
each child process is likely to be blessed into IPC::Run::Proc.
$kid->abort(), $kid->kill(), $kid->signal( $num_or_name ).
Write tests for /(full_)?results?/ subs.
Currently, pump() and run() only work on systems where select() works on the
filehandles returned by pipe(). This does *not* include ActiveState on Win32,
although it does work on cygwin under Win32 (thought the tests whine a bit).
I'd like to rectify that, suggestions and patches welcome.
Likewise start() only fully works on fork()/exec() machines (well, just
fork() if you only ever pass perl subs as subprocesses). There's
some scaffolding for calling Open3::spawn_with_handles(), but that's
untested, and not that useful with limited select().
Support for C<\@sub_cmd> as an argument to a command which
gets replaced with /dev/fd or the name of a temporary file containing foo's
output. This is like <(sub_cmd ...) found in bash and csh (IIRC).
Allow multiple harnesses to be combined as independent sets of processes
in to one 'meta-harness'.
Allow a harness to be passed in place of an \@cmd. This would allow
multiple harnesses to be aggregated.
Ability to add external file descriptors w/ filter chains and endpoints.
Ability to add timeouts and timing generators (i.e. repeating timeouts).
High resolution timeouts.
=head1 Win32 LIMITATIONS
=over
=item argument-passing rules are program-specific
Win32 programs receive all arguments in a single "command line" string.
IPC::Run assembles this string so programs using L<standard command line parsing
rules|https://docs.microsoft.com/en-us/cpp/cpp/main-function-command-line-args#parsing-c-command-line-arguments>
will see an C<argv> that matches the array reference specifying the command.
Some programs use different rules to parse their command line. Notable examples
include F<cmd.exe>, F<cscript.exe>, and Cygwin programs called from non-Cygwin
programs. Use L<IPC::Run::Win32Process> to call these and other nonstandard
programs.
=item batch files
Properly escaping a batch file argument depends on how the script will use that
argument, because some uses experience multiple levels of caret (escape
character) removal. Avoid calling batch files with arguments, particularly when
the argument values originate outside your program or contain non-alphanumeric
characters. Perl scripts and PowerShell scripts are sound alternatives. If you
do use batch file arguments, IPC::Run escapes them so the batch file can pass
them, unquoted, to a program having standard command line parsing rules. If the
batch file enables delayed environment variable expansion, it must disable that
feature before expanding its arguments. For example, if F<foo.cmd> contains
C<perl %*>, C<run ['foo.cmd', @list]> will create a Perl process in which
C<@ARGV> matches C<@list>. Prepending a C<setlocal enabledelayedexpansion> line
would make the batch file malfunction, silently. Another silent-malfunction
example is C<run ['outer.bat', @list]> for F<outer.bat> containing C<foo.cmd
%*>.
=item Fails on Win9X
If you want Win9X support, you'll have to debug it or fund me because I
don't use that system any more. The Win32 subsysem has been extended to
use temporary files in simple run() invocations and these may actually
work on Win9X too, but I don't have time to work on it.
=item May deadlock on Win2K (but not WinNT4 or WinXPPro)
Spawning more than one subprocess on Win2K causes a deadlock I haven't
figured out yet, but simple uses of run() often work. Passes all tests
on WinXPPro and WinNT.
=item no support yet for <pty< and >pty>
These are likely to be implemented as "<" and ">" with binmode on, not
sure.
=item no support for file descriptors higher than 2 (stderr)
Win32 only allows passing explicit fds 0, 1, and 2. If you really, really need to pass file handles, us Win32API:: GetOsFHandle() or ::FdGetOsFHandle() to
get the integer handle and pass it to the child process using the command
line, environment, stdin, intermediary file, or other IPC mechanism. Then
( run in 0.414 second using v1.01-cache-2.11-cpan-524268b4103 )