4

I have a perl script that calls an other perl script by using system()

it's like:

my $returnval= system("perl", $path,$val1, $val2,@myarray);

Because system() returns only the exit status but I want the script's output I want to use backticks.

I tried something like that:

my $returnval = `$path`;

how can I add the parameters the script should receive?

how should the other perl script's return code looks like? At the moment it's like

exit ($myreturnedvalue);

(how) Is it possible to return multiple values?

Tyzak
  • 2,430
  • 8
  • 38
  • 52
  • Regrettably, I do not understand the question about returning multiple values. Would you clarify? – thb Jun 03 '12 at 13:13
  • I want to call a script with parameters, then I want the script's output and this output, does it have to be a single value or can it be an array or two parameters like exit (x1,x2) – Tyzak Jun 03 '12 at 13:31
  • You can only return a piece of text (or binary data). If you want multiple values then the script you are calling needs to return a serialised data structure (space separated, JSON, XML, etc) that you parse in your Perl. – Quentin Jun 03 '12 at 13:34
  • ah, okay, so I have to work on the text for extracting the information I want, thanks :) – Tyzak Jun 03 '12 at 13:42
  • 2
    Are you trying to have perl functions in more than file within the program, or are you struggling to understand how to use `$?` in your program? `$output = ˋcmd arg1 arg2ˋ; $status = $?;` gets both output and status separately. – tchrist Jun 03 '12 at 20:39

5 Answers5

5

To go through the shell in order to move data from one perl script to another is not the best solution. You should know that backticks or qx() captures whatever is printed to STDOUT. Using exit ($var) from the other script is unlikely to be captured properly. You would need print $var. But don't do that.

Instead, make the other script into a module and use the subroutine directly. This is a simplistic example:

In bar.pm:

use strict;
use warnings;

package bar;  # declare our package

sub fooz {             # <--- Our target subroutine
    my $in = shift;    # passing the input
    return $in * 5;    # return value
}
1; # return value must be true

In main.pl:

use strict;
use warnings;
use bar;   # bar.pm must be in one path in @INC

my $foo = bar::fooz(12);  # calling fooz from our other perl script
print "Foo is $foo\n";

There is a lot more to learn, and I suggest you read up on the documentation.

TLP
  • 66,756
  • 10
  • 92
  • 149
4

You want IPC::System::Simple's capturex.

use IPC::System::Simple qw( capturex );
my $output = capturex("perl", $path, $val1, $val2, @myarray);

It even handles errors for you.

ikegami
  • 367,544
  • 15
  • 269
  • 518
  • 1
    Why the -1? The OP asked for a version of backticks where the command isn't subject to shell interpretation, and that's exactly what `capturex` is. – ikegami Jun 04 '12 at 05:53
3

The backticks simply work like a direct invocation one would make in a shell:

you@somewhere:~$ ./script.pl --key=value

Is basically the same as

my $returnval = `./script.pl --key=value`;
mjhennig
  • 671
  • 5
  • 11
2

For invoking other programs passing arguments and capturing output at the same time, I'm a big fan of IPC::Run:

use IPC::Run 'run';

my $exitcode = run [ $command, @args ], ">", \my $output;

# $exitcode contains the exit status and
# $output contains the command's STDOUT data
LeoNerd
  • 8,344
  • 1
  • 29
  • 36
1

Does this not do what you want?

my $returnval = `$path $val1 $val2 @myarray`;

@Quentin however adds this useful advice: If the value you want to pass is foo "bar then in shell you would have to do something like "foo \"bar". Using extra arguments to system will take card of that for you. Using backticks won't; you need to construct the shell command you want manually.

thb
  • 13,796
  • 3
  • 40
  • 68
  • It won't autoquote / escape the arguments – Quentin Jun 03 '12 at 13:12
  • @Quentin: Thank you for the advice. I admit that I do not know what autoquoting is. A quick grep through my Perl manpages turns up three, cryptic, passing references to "autoquoting" or "auto-quoting," but these do not explain; nor does a web search immediately turn up anything very informative. If you can spare a moment, would you explain a bit further? Thanks. – thb Jun 03 '12 at 13:22
  • I tried that and after that i tried `$path /$val1 /$val2 /@myarray`, both didn't work :> – Tyzak Jun 03 '12 at 13:29
  • 2
    If the value you want to pass is `foo "bar` then in shell you would have to do something like `"foo \"bar"`. Using extra arguments to `system` will take card of that for you. Using backticks won't, you need to construct the shell command you want manually. – Quentin Jun 03 '12 at 13:33
  • `$path \$val1 \$val2 \@myarray` works to call the function with the parameter. but the returned values seems not to fit. Do I have to write the return value into the exit funtion like: exit(value1); ? – Tyzak Jun 03 '12 at 13:41
  • @Quentin: If I knew how, I would correct my answer and transfer it to your user-ID for reputational credit. You are right, of course. At any rate, I'll do what I can to correct my answer on your advice now. – thb Jun 03 '12 at 13:44