.\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "System::Sub 3pm" .TH System::Sub 3pm "2019-02-01" "perl v5.28.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" System::Sub \- Wrap external command with a DWIM sub .SH "VERSION" .IX Header "VERSION" version 0.162800 .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use System::Sub \*(Aqhostname\*(Aq; # Just an example (use Sys::Hostname instead) \& \& # Scalar context : returns the first line of the output, without the \& # line separator \& my $hostname = hostname; \& \& # List context : returns a list of lines without their line separator \& use System::Sub \*(Aqls\*(Aq; \& my @files = ls \*(Aq\-a\*(Aq; \& \& # Process line by line \& ls \-a => sub { \& push @files, $_[0]; \& }; \& \& use System::Sub \*(Aqdf\*(Aq => [ \*(Aq@ARGV\*(Aq => [ \*(Aq\-P\*(Aq ] ]; # \-P for POSIX \& df => sub { \& return if $. == 1; # Skip the header line \& # Show the 6th and 5th columns \& printf "%s: %s\en", (split / +/, $_[0])[5, 4]; \& }; \& \& # Import with options \& use System::Sub ssh => [ \*(Aq$0\*(Aq => \*(Aq/usr/bin/ssh\*(Aq, \& \*(Aq@ARGV\*(Aq => [ qw< \-o RequestTTY=no > ] ]; \& \& # Handle exit codes \& use System::Sub \*(Aqzenity\*(Aq; # a GTK+ dialog display \& eval { \& zenity \-\-question \& => \-\-text => \*(AqHow are you today?\*(Aq \& => \-\-ok\-label => \*(AqFine!\*(Aq \& => \-\-cancel\-label => \*(AqTired.\*(Aq \& }; \& given ($? >> 8) { \& when (0) { \& } \& when (1) { \& } \& } \& \& # Import with a prototype (see perlsub) \& use System::Sub \*(Aqhostname()\*(Aq; # Empty prototype: no args allowed \& use System::Sub hostname => [ \*(Aq()\*(Aq => \*(Aq\*(Aq ]; # Alternate syntax \& use strict; \& # This will fail at compile time with "Too many arguments" \& hostname("xx"); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" See also \f(CW\*(C`System::Sub::AutoLoad\*(C'\fR for even simpler usage. .PP \&\f(CW\*(C`System::Sub\*(C'\fR provides in your package a sub that wraps the call to an external program. The return value is line(s) dependending on context (\f(CW\*(C`wantarray\*(C'\fR). .PP This may be what you need if you want to run external commands as easily as from a Unix shell script but with a perl-ish feel (contextual output). So this is not a universal module for running external programs (like IPC::Run) but instead a simpler interface for a common style of external programs. .PP \&\f(CW\*(C`System::Sub\*(C'\fR may be useful if: .IP "\(bu" 4 you want to run the command synchronously (like \f(CW\*(C`system\*(C'\fR or backquotes) .IP "\(bu" 4 the command .RS 4 .IP "\- is non-interactive (all the input is fed at start)" 4 .IX Item "- is non-interactive (all the input is fed at start)" .PD 0 .ie n .IP "\- input is @ARGV and ""STDIN""" 4 .el .IP "\- input is \f(CW@ARGV\fR and \f(CWSTDIN\fR" 4 .IX Item "- input is @ARGV and STDIN" .ie n .IP "\- output is ""STDOUT""" 4 .el .IP "\- output is \f(CWSTDOUT\fR" 4 .IX Item "- output is STDOUT" .IP "\- the exit code is what matters for errors" 4 .IX Item "- the exit code is what matters for errors" .ie n .IP "\- ""STDERR"" will not be captured, and will go to ""STDERR"" of your program." 4 .el .IP "\- \f(CWSTDERR\fR will not be captured, and will go to \f(CWSTDERR\fR of your program." 4 .IX Item "- STDERR will not be captured, and will go to STDERR of your program." .RE .RS 4 .RE .PD .PP The underlying implementation is currently IPC::Run, but there is no garantee that this will stay that way. IPC::Run works well enough on both Unix and Win32, but it has its own bugs and is very slow. .SH "IMPORT OPTIONS" .IX Header "IMPORT OPTIONS" Options can be set for the sub by passing an \s-1ARRAY\s0 just after the sub name on the \f(CW\*(C`use System::Sub\*(C'\fR line. .PP The sigil (\f(CW\*(C`$\*(C'\fR, \f(CW\*(C`@\*(C'\fR, \f(CW\*(C`%\*(C'\fR) is optional. .IP "\(bu" 4 \&\f(CW\*(C`()\*(C'\fR: prototype of the sub. See \*(L"Prototypes\*(R" in perlsub. .IP "\(bu" 4 \&\f(CW$0\fR: the path to the executable file. It will be expanded from \s-1PATH\s0 if it doesn't contain a directory separator. .IP "\(bu" 4 \&\f(CW@ARGV\fR: command arguments that will be inserted before the arguments given to the sub. This is useful if the command always require a basic set of arguments. .IP "\(bu" 4 \&\f(CW%ENV\fR: environment variables to set for the command. .IP "\(bu" 4 \&\f(CW\*(C`>\*(C'\fR: I/O layers for the data fed to the command. .IP "\(bu" 4 \&\f(CW\*(C`<\*(C'\fR: I/O layers for the data read from the command output. .IP "\(bu" 4 \&\f(CW\*(C`&?\*(C'\fR: sub that will be called if ($? >> 8) != 0. .Sp .Vb 4 \& sub { \& my $name = shift; # name of the sub \& my $code = shift; # exit code ($?) \& my $cmd = shift; # array ref to the executed command \& \& # Default implementation: \& require Carp; \& Carp::croak("$name error ".($code >> 8)); \& } .Ve .Sp Mnemonic: \f(CW\*(C`&\*(C'\fR is the sigil for subs and \f(CW$?\fR is the exit code of the last command. .SH "SUB USAGE" .IX Header "SUB USAGE" .SS "Arguments" .IX Subsection "Arguments" The scalar arguments of the sub are directly passed as arguments of the command. .PP The queue of the arguments may contain values of the following type (see \&\*(L"ref\*(R" in perlfunc): .IP "\(bu" 4 \&\f(CW\*(C`CODE\*(C'\fR .Sp A sub that will be called for each line of the output. The argument is the \&\f(CW\*(C`chomp\*(C'\fR\-ed line. .Sp .Vb 3 \& sub { \& my ($line) = @_; \& } .Ve .Sp This argument must always be the last one. .IP "\(bu" 4 \&\f(CW\*(C`REF\*(C'\fR .Sp A reference to a scalar containing the full input of the command. .IP "\(bu" 4 \&\f(CW\*(C`ARRAY\*(C'\fR .Sp A reference to an array containing the lines of the input of the command. \&\f(CW\*(C`\en\*(C'\fR will be appended at the end of each line. .SS "Return value(s)" .IX Subsection "Return value(s)" .IP "\(bu" 4 Scalar context .Sp Returns just the first line (based on \f(CW$/\fR), chomped or undef if no output. .IP "\(bu" 4 List context .Sp Returns a list of the lines of the output, based \f(CW$/\fR. The end-of-line chars (\f(CW$/\fR are not in the output. .IP "\(bu" 4 Void context .Sp If you do not specify a callback, the behavior is currently unspecified (suggestions welcome). .SH "SEE ALSO" .IX Header "SEE ALSO" .IP "\(bu" 4 Shell, distributed with Perl 5 to 5.14. Removed from core in 5.16. .IP "\(bu" 4 perlipc, perlfaq8 .IP "\(bu" 4 IPC::Run .IP "\(bu" 4 AnyEvent::Util::run .IP "\(bu" 4 System::Command .IP "\(bu" 4 Sys::Cmd .IP "\(bu" 4 Proc::Lite .IP "\(bu" 4 IPC::Open3 .IP "\(bu" 4 Sys::Cmd .IP "\(bu" 4 System .IP "\(bu" 4 System2 .IP "\(bu" 4 IPC::Cmd .IP "\(bu" 4 Capture::Tiny .SH "TRIVIA" .IX Header "TRIVIA" I dreamed about such a facility for a long time. I even worked for two years on a ksh framework that I created from scratch just because at the start of the project I didn't dare to bet on Perl because of the lack of readability of the code when most of the work is running other programs. .PP After that project I never really had the need to run the same command in many places of the code, and in many different ways. Until I had the need to wrap Git in the release script of my github-keygen project. I wrote the first version of the wrapper there, and quickly extracted it as this module. So, here is it! .PP Last but not least, the pun in the package name is intended. .SH "AUTHOR" .IX Header "AUTHOR" Olivier Mengué, \f(CW\*(C`dolmen@cpan.org\*(C'\fR. .SH "CONTRIBUTORS" .IX Header "CONTRIBUTORS" Philippe Bruhat (\s-1BOOK\s0 ). .PP See the Git log for details. .SH "COPYRIGHT & LICENSE" .IX Header "COPYRIGHT & LICENSE" Copyright © 2012 Olivier Mengué. .PP This library is free software; you can redistribute it and/or modify it under the same terms as Perl 5 itself.