Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re: capturing command output

by eyepopslikeamosquito (Canon)
on Jan 26, 2012 at 08:32 UTC ( #950040=note: print w/ replies, xml ) Need Help??


in reply to capturing command output

We tend to avoid the Windows shell in Perl scripts that run external commands in customer environments over which we have no control. Some years ago we got burnt because some of our customers use a misfeature of Windows cmd.exe, namely that without the /d option, cmd.exe executes stuff from one of the following Registry values:

HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun HKEY_CURRENT_USER\Software\Microsoft\Command Processor\AutoRun
before running your command. In one case, I remember there was a "cd" command in the customer autorun Registry which caused one of our Perl scripts to malfunction. We worked around it by replacing `some command 2>&1` with `cmd /d/c "some command" 2>&1`. An alternative workaround is to manipulate STDOUT and STDERR from perl, while taking care to call the Perl system function in such a way that the shell is not invoked.

To clarify, the two approaches are illustrated by the following two example programs:

use strict; use warnings; my $cmd = 'perl -le "print qq{to stdout};print STDERR qq{to stde +rr};exit 42"'; my $cmdhack = qq{cmd /d/c $cmd 2>&1}; # works # my $cmdhack = qq{cmd /d/c "$cmd" 2>&1}; # also works (despite bizar +re quoting) print "run:$cmdhack:\n"; my $out = `$cmdhack`; my $rc = $? >> 8; print "rc=$rc, stdout/stderr of command follows:\n"; print $out;

and:

use strict; use warnings; my $outfile = 'ff.tmp'; my $exe = $^X; my @args = ( 'perl', '-le', 'print qq{to stdout};print STDERR qq{to + stderr};exit 42' ); print "run exe:$exe:args:@args:\n"; print STDERR "here we go to stderr\n"; open(SAVOUT, ">&STDOUT") or die "error: save original STDOUT: $!"; open(SAVERR, ">&STDERR") or die "error: save original STDERR: $!"; open(STDOUT, '>', $outfile) or die "error: create '$outfile': $!"; open(STDERR, '>&STDOUT') or die "error: redirect '$outfile': $!"; system { $exe } @args; my $rc = $? >> 8; open(STDOUT, ">&SAVOUT") or die "error: restore STDOUT: $!"; open(STDERR, ">&SAVERR") or die "error: restore STDERR: $!"; close(SAVERR) or die "error: close SAVERR: $!"; close(SAVOUT) or die "error: close SAVOUT: $!"; print "rc=$rc\n"; print STDERR "rc=$rc to STDERR\n";
Improvements welcome.

Update: tidied up and clarified the example code.


Comment on Re: capturing command output
Select or Download Code

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://950040]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (7)
As of 2014-07-24 11:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (160 votes), past polls