X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FShell.pm;h=a84d9a9f67aac4d9ae9f2b89af38eb2fd69c7a37;hb=1d74b28c229b5172175a0073070beb529386ac4f;hp=c2f522cae309363daeac532639022f40f59c10ad;hpb=8d5b6de5e1eb7bf5df60c4299d3d7e78abf5d747;p=p5sagit%2Fp5-mst-13.2.git
diff --git a/lib/Shell.pm b/lib/Shell.pm
index c2f522c..a84d9a9 100644
--- a/lib/Shell.pm
+++ b/lib/Shell.pm
@@ -1,12 +1,14 @@
package Shell;
-use 5.005_64;
+use 5.006_001;
use strict;
use warnings;
-our($capture_stderr, $VERSION, $AUTOLOAD);
+use File::Spec::Functions;
-$VERSION = '0.3';
+our($capture_stderr, $raw, $VERSION, $AUTOLOAD);
-sub new { bless \$VERSION, shift } # Nothing better to bless
+$VERSION = '0.6';
+
+sub new { bless \my $foo, shift }
sub DESTROY { }
sub import {
@@ -28,10 +30,15 @@ sub AUTOLOAD {
shift if ref $_[0] && $_[0]->isa( 'Shell' );
my $cmd = $AUTOLOAD;
$cmd =~ s/^.*:://;
+ my $null = File::Spec::Functions::devnull();
+ $Shell::capture_stderr ||= 0;
eval <<"*END*";
sub $AUTOLOAD {
+ shift if ref \$_[0] && \$_[0]->isa( 'Shell' );
if (\@_ < 1) {
- \$Shell::capture_stderr ? `$cmd 2>&1` : `$cmd`;
+ \$Shell::capture_stderr == 1 ? `$cmd 2>&1` :
+ \$Shell::capture_stderr == -1 ? `$cmd 2>$null` :
+ `$cmd`;
} elsif ('$^O' eq 'os2') {
local(\*SAVEOUT, \*READ, \*WRITE);
@@ -61,7 +68,8 @@ sub AUTOLOAD {
} else {
my \$a;
my \@arr = \@_;
- if ('$^O' eq 'MSWin32') {
+ unless( \$Shell::raw ){
+ if ('$^O' eq 'MSWin32') {
# XXX this special-casing should not be needed
# if we do quoting right on Windows. :-(
#
@@ -77,13 +85,15 @@ sub AUTOLOAD {
s/\\\\\\\\"/\\\\\\\\"""/g;
\$_ = qq["\$_"] if /\\s/;
}
- } else {
+ } else {
for (\@arr) {
s/(['\\\\])/\\\\\$1/g;
\$_ = \$_;
- }
+ }
+ }
}
- push \@arr, '2>&1' if \$Shell::capture_stderr;
+ push \@arr, '2>&1' if \$Shell::capture_stderr == 1;
+ push \@arr, '2>$null' if \$Shell::capture_stderr == -1;
open(SUBPROC, join(' ', '$cmd', \@arr, '|'))
or die "Can't exec $cmd: \$!\\n";
if (wantarray) {
@@ -114,10 +124,82 @@ Shell - run shell commands transparently within perl
=head1 SYNOPSIS
-See below.
+ use Shell qw(cat ps cp);
+ $passwd = cat('new;
+ print $sh->ls('-l');
=head1 DESCRIPTION
+=head2 Caveats
+
+This package is included as a show case, illustrating a few Perl features.
+It shouldn't be used for production programs. Although it does provide a
+simple interface for obtaining the standard output of arbitrary commands,
+there may be better ways of achieving what you need.
+
+Running shell commands while obtaining standard output can be done with the
+C operator, or by calling C with a filename expression that
+ends with C<|>, giving you the option to process one line at a time.
+If you don't need to process standard output at all, you might use C
+(in preference of doing a print with the collected standard output).
+
+Since Shell.pm and all of the aforementioned techniques use your system's
+shell to call some local command, none of them is portable across different
+systems. Note, however, that there are several built in functions and
+library packages providing portable implementations of functions operating
+on files, such as: C, C and C, C and C,
+C, C, C, C etc.
+
+Using Shell.pm while importing C creates a subroutine C in the
+namespace of the importing package. Calling C with arguments C,
+C,... results in a shell command C, where the
+function name and the arguments are joined with a blank. (See the subsection
+on Escaping magic characters.) Since the result is essentially a command
+line to be passed to the shell, your notion of arguments to the Perl
+function is not necessarily identical to what the shell treats as a
+command line token, to be passed as an individual argument to the program.
+Furthermore, note that this implies that C is callable by file name
+only, which frequently depends on the setting of the program's environment.
+
+Creating a Shell object gives you the opportunity to call any command
+in the usual OO notation without requiring you to announce it in the
+C