/[cvs]/nfo/perl/scripts/sshwrap/Shell.pm
ViewVC logotype

Annotation of /nfo/perl/scripts/sshwrap/Shell.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations)
Mon Jan 20 19:01:04 2003 UTC (21 years, 5 months ago) by joko
Branch: MAIN
CVS Tags: v002, HEAD
+ initial check-in

1 joko 1.1 package Shell;
2     use 5.005_64;
3     use strict;
4     use warnings;
5     our($capture_stderr, $VERSION, $AUTOLOAD);
6    
7     $VERSION = '0.4';
8    
9     sub new { bless \$VERSION, shift } # Nothing better to bless
10     sub DESTROY { }
11    
12     sub get_coderef {
13     my $codepack = shift;
14     my $method = shift;
15     $codepack || return '[error]';
16     $method ||= '';
17     $method && ($codepack .= '::');
18     return eval '\&' . $codepack . $method . ';';
19     }
20    
21     sub import {
22     my $self = shift;
23     my ($callpack, $callfile, $callline) = caller;
24     my @EXPORT;
25     if (@_) {
26     @EXPORT = @_;
27     } else {
28     @EXPORT = 'AUTOLOAD';
29     }
30     foreach my $sym (@EXPORT) {
31     no strict 'refs';
32     *{"${callpack}::$sym"} = get_coderef($self, $sym);
33     }
34     }
35    
36     sub AUTOLOAD {
37     shift if ref $_[0] && $_[0]->isa( 'Shell' );
38     my $cmd = $AUTOLOAD;
39     $cmd =~ s/^.*:://;
40     eval <<"*END*";
41     sub $AUTOLOAD {
42     if (\@_ < 1) {
43     \$Shell::capture_stderr ? `$cmd 2>&1` : `$cmd`;
44     } elsif ('$^O' eq 'os2') {
45     local(\*SAVEOUT, \*READ, \*WRITE);
46    
47     open SAVEOUT, '>&STDOUT' or die;
48     pipe READ, WRITE or die;
49     open STDOUT, '>&WRITE' or die;
50     close WRITE;
51    
52     my \$pid = system(1, '$cmd', \@_);
53     die "Can't execute $cmd: \$!\\n" if \$pid < 0;
54    
55     open STDOUT, '>&SAVEOUT' or die;
56     close SAVEOUT;
57    
58     if (wantarray) {
59     my \@ret = <READ>;
60     close READ;
61     waitpid \$pid, 0;
62     \@ret;
63     } else {
64     local(\$/) = undef;
65     my \$ret = <READ>;
66     close READ;
67     waitpid \$pid, 0;
68     \$ret;
69     }
70     } else {
71     my \$a;
72     my \@arr = \@_;
73     if ('$^O' eq 'MSWin32') {
74     # XXX this special-casing should not be needed
75     # if we do quoting right on Windows. :-(
76     #
77     # First, escape all quotes. Cover the case where we
78     # want to pass along a quote preceded by a backslash
79     # (i.e., C<"param \\""" end">).
80     # Ugly, yup? You know, windoze.
81     # Enclose in quotes only the parameters that need it:
82     # try this: c:\> dir "/w"
83     # and this: c:\> dir /w
84     for (\@arr) {
85     s/"/\\\\"/g;
86     s/\\\\\\\\"/\\\\\\\\"""/g;
87     \$_ = qq["\$_"] if /\\s/;
88     }
89     } else {
90     for (\@arr) {
91     s/(['\\\\])/\\\\\$1/g;
92     \$_ = \$_;
93     }
94     }
95     push \@arr, '2>&1' if \$Shell::capture_stderr;
96     open(SUBPROC, join(' ', '$cmd', \@arr, '|'))
97     or die "Can't exec $cmd: \$!\\n";
98     if (wantarray) {
99     my \@ret = <SUBPROC>;
100     close SUBPROC; # XXX Oughta use a destructor.
101     \@ret;
102     } else {
103     local(\$/) = undef;
104     my \$ret = <SUBPROC>;
105     close SUBPROC;
106     \$ret;
107     }
108     }
109     }
110     *END*
111    
112     die "$@\n" if $@;
113     goto &$AUTOLOAD;
114     }
115    
116     1;
117    
118     __END__
119    
120     =head1 NAME
121    
122     Shell - run shell commands transparently within perl
123    
124     =head1 SYNOPSIS
125    
126     See below.
127    
128     =head1 DESCRIPTION
129    
130     Date: Thu, 22 Sep 94 16:18:16 -0700
131     Message-Id: <9409222318.AA17072@scalpel.netlabs.com>
132     To: perl5-porters@isu.edu
133     From: Larry Wall <lwall@scalpel.netlabs.com>
134     Subject: a new module I just wrote
135    
136     Here's one that'll whack your mind a little out.
137    
138     #!/usr/bin/perl
139    
140     use Shell;
141    
142     $foo = echo("howdy", "<funny>", "world");
143     print $foo;
144    
145     $passwd = cat("</etc/passwd");
146     print $passwd;
147    
148     sub ps;
149     print ps -ww;
150    
151     cp("/etc/passwd", "/tmp/passwd");
152    
153     That's maybe too gonzo. It actually exports an AUTOLOAD to the current
154     package (and uncovered a bug in Beta 3, by the way). Maybe the usual
155     usage should be
156    
157     use Shell qw(echo cat ps cp);
158    
159     Larry
160    
161    
162     If you set $Shell::capture_stderr to 1, the module will attempt to
163     capture the STDERR of the process as well.
164    
165     The module now should work on Win32.
166    
167     Jenda
168    
169     There seemed to be a problem where all arguments to a shell command were
170     quoted before being executed. As in the following example:
171    
172     cat('</etc/passwd');
173     ls('*.pl');
174    
175     really turned into:
176    
177     cat '</etc/passwd'
178     ls '*.pl'
179    
180     instead of:
181    
182     cat </etc/passwd
183     ls *.pl
184    
185     and of course, this is wrong.
186    
187     I have fixed this bug, it was brought up by Wolfgang Laun [ID 20000326.008]
188    
189     Casey
190    
191     =head2 OBJECT ORIENTED SYNTAX
192    
193     Shell now has an OO interface. Good for namespace conservation
194     and shell representation.
195    
196     use Shell;
197     my $sh = Shell->new;
198     print $sh->ls;
199    
200     Casey
201    
202     =head1 AUTHOR
203    
204     Larry Wall
205    
206     Changes by Jenda@Krynicky.cz and Dave Cottle <d.cottle@csc.canterbury.ac.nz>
207    
208     Changes and bug fixes by Casey Tweten <crt@kiski.net>
209    
210     =cut

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed