Re: Capture Exit Code Using Pipe & Tee
by merlyn (Sage) on Jan 31, 2007 at 19:50 UTC
|
Do the tee yourself in Perl... that'd be a simple operation. Something like:
open my $make, "make -f params |" or die;
open my $logger, ">>build.log" or die;
while (<$make>) { print $logger $_; print }
close $make; # to get $?
my $exit = $?;
close $logger;
| [reply] [d/l] |
|
Always check the return value of close. You might be e.g. sitting on a NFS share.
--shmem
_($_=" "x(1<<5)."?\n".q·/)Oo. G°\ /
/\_¯/(q /
---------------------------- \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
| [reply] |
|
I've tried your suggestion. I can't seem to get it to write anything anywhere now. Ideally I would like it to be real-time. I can't see in the example where the execution of make is taking place.
Thanks for your help!!
| [reply] |
|
The make is invoked via open, which returns the process ID of the spawned command.
merlyn's code should work alright, with a slight modification
open my $make, "make -f params 2>&1 |" or die;
to get make's STDERR into the spawning shell's STDOUT. Do you get any errors reported?
--shmem
_($_=" "x(1<<5)."?\n".q·/)Oo. G°\ /
/\_¯/(q /
---------------------------- \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
| [reply] [d/l] |
Re: Capture Exit Code Using Pipe & Tee
by shmem (Chancellor) on Jan 31, 2007 at 21:55 UTC
|
You need a more elaborate construct to get the return value from make, if you want to execute it in a pipeline via /bin/sh. Try this (untested):
chop (my $status = `((make -f $params 2>&1 3>&-; echo \$? >&3 ) | tee
+-a build.log 1>&2 3>&- ) 3>&1`);
print "make exit status: $status\n";
update: added backslash to escape $?
--shmem
_($_=" "x(1<<5)."?\n".q·/)Oo. G°\ /
/\_¯/(q /
---------------------------- \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
| [reply] [d/l] |
Re: Capture Exit Code Using Pipe & Tee
by ambrus (Abbot) on Jan 31, 2007 at 22:14 UTC
|
If your shell is bash, check out the PIPESTATUS shell parameter. For example, $command = "make -f <parameters> 2>&1 | tee -a build.log; let \\!PIPESTATUS"; might work, but I haven't tested it.
| [reply] [d/l] |
|
merlyn's answer was dead on, for some reason it earlier it wasn't returning an error code, now with a minor tweak to merlyn's code I was able to get it working exactly like I wanted. THANKS A MILLION! This is a best place on the net for anything perl. I will be donating some $$$....
my code for completeness:
open MAKE, "make -f <params> 2>&1 |" or die;
open (LOGFILE, ">>build.log") or die;
while (<MAKE>) { print LOGFILE $_; print }
close MAKE; # to get $?
my $exit = $? >> 8;
close LOGFILE;
Edit: g0n - code tags | [reply] [d/l] |
|
the code wasn't actually returning the error code for the make file as far as i could tell.
I used it to run any program, and had to add this at the end:
exit $exit;
| [reply] [d/l] |
|
|
PIPESTATUS does indeed work when using Bash. Nice trick!
false | tee /dev/null
[ $PIPESTATUS -eq 0 ] || exit $PIPESTATUS
---
"A Jedi uses the Force for knowledge and defense, never for attack."
| [reply] [d/l] |
Re: Capture Exit Code Using Pipe & Tee
by ikegami (Patriarch) on Jan 31, 2007 at 20:55 UTC
|
The exit value is always 0, because it's returning the tee value, and not make. Any and all help is very apprciated.
Not quite. It's returning the error code of the shell invoked to execute the command. system sometimes, but not always, passes the command to /bin/sh. This is one of those times. See the docs for details.
| [reply] [d/l] [select] |
|
Both true and untrue misleading(?). It's getting the return/error code of the shell, yes. However, the shell is getting it from the tee command. If tee were to return 1, the shell would return 1, regardless of what make did.
merlyn's answer is definitely the right track. Doing this in perl is actually not that bad, and though it may take more code than shmem's response, I'm not sure it'd be less readable ;-)
| [reply] |
|
| [reply] [d/l] [select] |
Re: Capture Exit Code Using Pipe & Tee
by ikegami (Patriarch) on Jul 08, 2010 at 22:21 UTC
|
Instead of reimplementing one of the commands in Perl, you can be the shell!
use strict;
use warnings;
use IPC::Open3 qw( open3 );
my $make_file = 'Makefile';
open(local *TO_MAKE, '<&', *STDIN) or die;
*TO_MAKE if 0; # Avoid spurious warning.
my $make_pid = open3(
'<&TO_MAKE',
local *FR_MAKE,
undef,
'make', '-f', $make_file,
);
*FR_MAKE if 0; # Avoid spurious warning.
my $tee_pid = open3(
'<&FR_MAKE',
'>&STDOUT',
undef,
'tee', '-a', 'build.log',
);
waitpid($make_pid, 0);
print("$?\n");
waitpid($tee_pid, 0);
print("$?\n");
Duplicating our STDIN instead of using '<&STDIN' is necessary since open3 closes the handle we pass for the child's STDIN.
| [reply] [d/l] [select] |