integrate cfgperl contents into mainline
[p5sagit/p5-mst-13.2.git] / lib / Shell.pm
CommitLineData
a0d0e21e 1package Shell;
17f410f9 2use 5.005_64;
6570f784 3our($capture_stderr, $VERSION);
a0d0e21e 4
253924a2 5$VERSION = '0.2';
4633a7c4 6
a0d0e21e 7sub import {
8 my $self = shift;
9 my ($callpack, $callfile, $callline) = caller;
10 my @EXPORT;
11 if (@_) {
12 @EXPORT = @_;
13 }
14 else {
15 @EXPORT = 'AUTOLOAD';
16 }
17 foreach $sym (@EXPORT) {
18 *{"${callpack}::$sym"} = \&{"Shell::$sym"};
19 }
20};
21
22AUTOLOAD {
23 my $cmd = $AUTOLOAD;
24 $cmd =~ s/^.*:://;
253924a2 25 eval <<"*END*";
26 sub $AUTOLOAD {
4633a7c4 27 if (\@_ < 1) {
253924a2 28 \$Shell::capture_stderr ? `$cmd 2>&1` : `$cmd`;
4633a7c4 29 }
253924a2 30 elsif ('$^O' eq 'os2') {
4633a7c4 31 local(\*SAVEOUT, \*READ, \*WRITE);
32
33 open SAVEOUT, '>&STDOUT' or die;
34 pipe READ, WRITE or die;
35 open STDOUT, '>&WRITE' or die;
36 close WRITE;
37
253924a2 38 my \$pid = system(1, '$cmd', \@_);
39 die "Can't execute $cmd: \$!\\n" if \$pid < 0;
4633a7c4 40
41 open STDOUT, '>&SAVEOUT' or die;
42 close SAVEOUT;
43
44 if (wantarray) {
45 my \@ret = <READ>;
46 close READ;
47 waitpid \$pid, 0;
48 \@ret;
49 }
50 else {
51 local(\$/) = undef;
52 my \$ret = <READ>;
53 close READ;
54 waitpid \$pid, 0;
55 \$ret;
56 }
a0d0e21e 57 }
58 else {
253924a2 59 my \$a;
60 my \@arr = \@_;
61 if ('$^O' eq 'MSWin32') {
62 # XXX this special-casing should not be needed
63 # if we do quoting right on Windows. :-(
64 #
65 # First, escape all quotes. Cover the case where we
66 # want to pass along a quote preceded by a backslash
67 # (i.e., C<"param \\""" end">).
68 # Ugly, yup? You know, windoze.
69 # Enclose in quotes only the parameters that need it:
70 # try this: c:\> dir "/w"
71 # and this: c:\> dir /w
72 for (\@arr) {
73 s/"/\\\\"/g;
74 s/\\\\\\\\"/\\\\\\\\"""/g;
6570f784 75 \$_ = qq["\$_"] if /\\s/;
253924a2 76 }
77 }
78 else {
79 for (\@arr) {
80 s/(['\\\\])/\\\\\$1/g;
81 \$_ = "'\$_'";
82 }
83 }
84 push \@arr, '2>&1' if \$Shell::capture_stderr;
85 open(SUBPROC, join(' ', '$cmd', \@arr, '|'))
86 or die "Can't exec $cmd: \$!\\n";
a0d0e21e 87 if (wantarray) {
88 my \@ret = <SUBPROC>;
89 close SUBPROC; # XXX Oughta use a destructor.
90 \@ret;
91 }
92 else {
93 local(\$/) = undef;
94 my \$ret = <SUBPROC>;
95 close SUBPROC;
96 \$ret;
97 }
98 }
99 }
253924a2 100*END*
101
102 die "$@\n" if $@;
a0d0e21e 103 goto &$AUTOLOAD;
104}
105
1061;
a5f75d66 107__END__
108
109=head1 NAME
110
111Shell - run shell commands transparently within perl
112
113=head1 SYNOPSIS
114
115See below.
116
117=head1 DESCRIPTION
118
119 Date: Thu, 22 Sep 94 16:18:16 -0700
120 Message-Id: <9409222318.AA17072@scalpel.netlabs.com>
121 To: perl5-porters@isu.edu
122 From: Larry Wall <lwall@scalpel.netlabs.com>
123 Subject: a new module I just wrote
124
125Here's one that'll whack your mind a little out.
126
127 #!/usr/bin/perl
128
129 use Shell;
130
131 $foo = echo("howdy", "<funny>", "world");
132 print $foo;
133
134 $passwd = cat("</etc/passwd");
135 print $passwd;
136
137 sub ps;
138 print ps -ww;
139
140 cp("/etc/passwd", "/tmp/passwd");
141
142That's maybe too gonzo. It actually exports an AUTOLOAD to the current
143package (and uncovered a bug in Beta 3, by the way). Maybe the usual
144usage should be
145
146 use Shell qw(echo cat ps cp);
147
148Larry
149
150
253924a2 151If you set $Shell::capture_stderr to 1, the module will attempt to
152capture the STDERR of the process as well.
153
154The module now should work on Win32.
155
156 Jenda
157
a5f75d66 158=head1 AUTHOR
159
160Larry Wall
161
253924a2 162Changes by Jenda@Krynicky.cz and Dave Cottle <d.cottle@csc.canterbury.ac.nz>
163
a5f75d66 164=cut