Best way to capture output from system command to a text file?
40,409
Solution 1
Same as MVS's answer, but modern and safe.
use strict;
use warnings;
open (my $file, '>', 'output.txt') or die "Could not open file: $!";
my $output = `example.exe`;
die "$!" if $?;
print $file $output;
easier
use strict;
use warnings;
use autodie;
open (my $file, '>', 'output.txt');
print $file `example.exe`;
if you need both STDOUT and STDERR
use strict;
use warnings;
use autodie;
use Capture::Tiny 'capture_merged';
open (my $file, '>', 'output.txt');
print $file capture_merged { system('example.exe') };
Solution 2
Redirecting the output with plain > will only catch STDOUT. If you also want to catch STDERR, use 2>&1:
perl -e 'system("dir blablubblelel.txt >out.txt 2>&1");'
For more details, see Perlmonks
Solution 3
When you want recirect output permanently, you can do:
#redirect STDOUT before calling other functions
open STDOUT,'>','outputfile.txt' or die "can't open output";
system('ls;df -h;echo something'); #all will be redirected.
Author by
int80h
Updated on July 05, 2022Comments
-
int80h almost 2 years
I’m trying to capture output from using Perl’s
system
function to execute and redirect a system command’s ouptut to a file, but for some reason I’m not getting the whole output.I’m using the following method:
system("example.exe >output.txt");
What’s wrong with this code, or is there an alternative way of doing the same thing?
-
tchrist over 12 yearsI really cannot imagine why you would do all that, not even the first. And you still missed stderr.
-
Joel Berger over 12 yearsFirst of all, this post began as a comment on the outdated practices in MVS's answer. Second I didn't do "all that", just checked what I should. Third if it is "all that" it just shows how nice
autodie
is. And fourth, how did I missSTDERR
? Fifth, yes you can do it all with shell redirection, but Frank already did that, and I don't trust the Windows shell/ I don't have a windows computer to test anything on so lean on solved wheels. -
Joel Berger over 12 years@tchrist, Other than shell redirection, how would you do it?
-
MVS over 12 yearsJust to clarify, my answer was meant to be a code snippet just like in the question. I didn't include strict or warnings because I assume he already has them. My mistake about
or
vs.||
, though. Either one works here, butor
is better for error checking, so I'll edit that. I was coding in PHP at the time and got my wires crossed a little. As for the rest, TMTOWTDI. :) -
Joel Berger over 12 years@MVS, no, its the lexical filehandle, the 3-arg open and checking the status of the backtick execution that I care about. don't care about the
or
, and I always put instrict
andwarnings
for any newbies present -
tchrist over 12 yearsPerl knows about
2>
stuff even on Micosoft-ridden ports. Ilya put it in. And even he didn’t, we certainly know how to dup our descriptors correctly. -
tchrist over 12 years@Joel I would simply use Perl’s
system
for what it was designed for, is how I would do it. It’s smarter than you might think, and really, if it isn’t good enough to handle so basic an operation as this one, then there is a Problem that needs fixing.if (system("proggie >outfile 2>&1") != 0) { ... }
-
Joel Berger over 12 years@tchrist, I do not know the shell commands well. Franks answer already had that so, I'm not sure why my answer is worth your ire. Further it seems that other people have the same concerns/lack-of-shell-knowledge as I have stackoverflow.com/q/7809740/468327 so I think its worth knowing a second way of accomplishing this.
-
Znik about 10 yearsthis is not answer. this method use asker but wants another.
-
Znik about 10 yearsthis doesn't redirect output for for commands called by 'system' function. This workaround has big but. When 'example.exe' generate very big output, you can easly overflow available memory.
-
DataGuru almost 10 yearsCapture::Tiny has now been extended with Capture::Tiny::Extended, you can have ($out, $err, $retval ) = capture { system( "run system command" ) } check out rpm.pbone.net/index.php3/stat/45/idpl/21405428/numer/3/nazwa/… for more information
-
Chad Nouis over 8 yearsThis example merely adds quotation marks around output.txt. Quotes aren't necessary for a file name without spaces. Its effect is identical to that of the question.
-
Marki555 over 2 years@DataGuru Capture::Tiny::Extended seems to be abandoned since 2011 and most of its features are already in original Capture::Tiny.
-
Marki555 over 2 yearsCapture::Tiny::Extended seems to be abandoned since 2011 and most of its features are already in original Capture::Tiny (last updated in 2018), so better use this one.