Reputation: 5399
I've a problem. In my Perl script I execute a java program which print both to stdout and stderr streams. Could you please give me a peace of advice of how I can redirect stderr to file only and stdout to the same file and to the console. tee is not applicable here because I also need a return code of the java program. Any ideas?
Thanks in advance!
Upvotes: 0
Views: 3084
Reputation: 3635
Bash includes an option pipefail
to have pipelines return the rightmost failure code instead of the rightmost exit code.
You might be able to take something like this to run your command in bash with pipefail
set.
my $ret = system( q{bash -c 'set -o pipefail; java command 2>>~/test_file | tee -a ~/test_file'} );
Upvotes: 0
Reputation: 101
Use IPC::Open3 to call the java program. Use IO::Select to read from the file handles. Do the writing yourself.
IPC::Open3 does a fork() and exec() for you so you get the return value using waitpid.
Upvotes: 3
Reputation: 19
You can try to following by redirect stderr into stdout.
my $retvar = system("java -jar prog.jar 2>&1 > output.log ");
Upvotes: 1
Reputation: 7526
Consider doing it thusly:
perl -le 'qx(java -jar prog.jar>output.log 2>&1);$rc=$?;print "rc=",$rc<0 ? -1:$rc>>8'
This will redirect both STDOUT and STDERR into your file and capture and print the return code. Examine (or cat
) the output file to the console as necessary. Look at qx and system for more insight.
UPDATE: Another way is something like this (i.e. secondarily writing the output file):
my $msg=qx(java -jar prog.jar 2>&1);
my $rc=$? < 0 ? -1 : $? >>8, "\n";
print $msg, "rc=$rc\n";
open my $fh, '>', 'output.log' or die "$!\n";
print {$fh} $msg, "rc=$rc\n";
Upvotes: 1
Reputation: 149
You can't do that directly from the shell (without tee).
Maybe you could redirect to a file, then open that file from inside the perl script and print to the console. Something like:
use Path::Class; # Handy module, but you can do without
my $retvar = system("java -jar prog.jar >stdout.log 2>stderr.log ");
my $output = file('.', 'stdout.log')->slurp();
print $output; # or print STDERR $output;
Hope this helps a bit. It still keeps the file separated, which is maybe not what you wanted.
Michele.
Upvotes: 1
Reputation: 1473
If you're under *nix you should look up "tee" command.
You should probably do something like:
perl script.pl 2>stderr.out | tee stdout.out
Upvotes: 0