1

I have a perl script in which I am forking a child process. Here is what I am doing:

my $pid = fork;

if($pid) {
# parent 
waitpid($pid, 0);
}
else {
exec("some other script X.pl");
}

Now, I wanted to capture the error of X.pl to display in my script. But as I understand this is not possible suing exec.

What are the other options I have?

How can I use open3 in my case?

Thanks!

user225206
  • 63
  • 6
  • 1
    What kind of error will `X.pl` generate, will it exit with error code or it will display on the standard output? – Logan Ding Oct 16 '13 at 08:31
  • It'll display it on STDOUT and will also return the exit code. I know how to capture the exit code, but I also want to get the error message. – user225206 Oct 16 '13 at 10:05
  • 1
    both the `open` built-in and `open3` accept a dash as the command argument indicating that you actually want to fork instead of running an external program. Read the docs! – salva Oct 16 '13 at 13:23

1 Answers1

0

If what you are looking for is just the return value of X.pl you can use

my $returnValue = $?>>8;

See and http://perldoc.perl.org/functions/system.html for more Information. By the way, if all your parent does is wait for the child, using system is probably better than fork and exec by Hand.

edit:

To capture STDOUT you can use

my $output = qx/X.pl/;

instead of forking and exec. This will still alow you to inspect $? for the return values. To not have perl interpolate the stuff in the command you can use also use qx'command' to pass the command to the System without changing anything. If you want your parent to do stuff while waiting for X.pl but still want return value and Output of X.pl i would suggest looking into expect. http://search.cpan.org/~rgiersig/Expect-1.15/Expect.pod

tvkanters
  • 3,519
  • 4
  • 29
  • 45
DeVadder
  • 1,404
  • 10
  • 18
  • I used system call: my $out = system("x.pl --command line args"); But the variable $out contains a numeric value. – user225206 Oct 16 '13 at 10:38
  • Yes, the return value of System is the same value you can find in $?. Meaning rightshifting by 8 yields the return value of the started program. my $returnValue = (System ("X.pl")) >> 8; – DeVadder Oct 16 '13 at 11:02
  • Ya, but how do I get the string return Value? – user225206 Oct 16 '13 at 11:29
  • String return value? If you want STDOUT use `qx/X.pl/` as i mentioned. If it is STDERR you are after, easiest is to still use qx// but Change Output. `$output = qx/X.pl 2>&1/;` gives you STDOUT and STDERR and `$output = qx"X.pl 2>&1 1>/dev/null";` gives you just STDERR while discarding STDOUT. – DeVadder Oct 16 '13 at 11:54
  • Thing is, my script, which is to come inside, qx// contains a lot of things. qx/"su - $user -c \"sudo x.pl -option 1 value1 -option2" \"/; and qx is not able to process this properly. – user225206 Oct 16 '13 at 12:44
  • That is probably because qx// interpolates the string and tries to make sense of all the " and \ and $. If you use qx' ' instead, it should pass everything between the ' ' without changing anything to the System. Don't use " " in that case unless you would use them as well when inputting your command. If your command also has ' you Need to escape them by using \' but this is the only interpolating qx' ' does. – DeVadder Oct 16 '13 at 12:58
  • too late edit: Be sure to use ' and not backticks (in fact qx// is just a fancy way of using `` and better because you can use qx'' ) ^^ – DeVadder Oct 16 '13 at 13:04
  • So with qx'' no interpolation of the command is done. What if my command has 1-2 variables that I do want to get interpolated? – user225206 Oct 16 '13 at 13:11
  • Then either use `qx//` and escape (put a backslash in front) any Special caracters you want to pass on or use something like `my $command = 'Stuff not to be interpolated ', $perlvariable ,' more literal stuff'; qx/$command/;` and use the fact that `qx//` interpolates only once and thereby passes the string in `$command` as it is in there. – DeVadder Oct 16 '13 at 13:43