Perl how to pass array as an argument to another Perl script

2k Views Asked by At

I have a 2 perl scripts where primary_script.pl would be calling secondary_script.pl script by passing array as an argument.

My code is shown below:
primary_script.pl

#!/usr/bin/perl

use Data::Dumper;
my @array = qw/1 2 3 4 5/;
print Dumper(\@array);

my $arr = \@array;

system("perl secondary_script.pl $arr") ;

print "END\n";


secondary_script.pl

#!/usr/bin/perl

my @var = @{$ARGV[0]};
print @var."\n";

I am passing array reference as an arguments to secondary_script.pl and from there I am dereferencing that array. Here @var prints 0 as a result instead of array contents which is been passed by primary_script.pl.

Is this right way to pass array as an argument to another perl script?

1

There are 1 best solutions below

2
On

You can just pass the arguments, using system in the list form:

 system $^X, $program_name, @array;

The list form bypasses the shell so it doesn't interpret metacharacters from your arguments (such as ; and & in the shell).

The $^X is the path the perl that is currently running, which is likely the one you want rather than searching the PATH again.

There are are complications to keep the second program to interpret your arguments as you want. I cover some of those in Quoting the Shell.

You'd have to say more about what you are trying to do to get better advice.

Back to your programs

Let's look at a few other things in your programs.

In _secondary_script.pl_, you try to dereference the argument list. But, @ARGV is a plain, named array. You don't need to dereference it. You could write:

print "@ARGV\n";

Putting the argument list in double quotes interpolates it by putting spaces between the elements. That way, you're not playing tricks with references.

If you're trying to pass complex data rather than simple arguments, you might consider some sort of serialization (JSON, Sereal, whatever) and outputting to standard output and reading from standard input:

use Data::Dumper;
my @array = qw/1 2 3 4 5/;
print Dumper(\@array);

Then, in the other program:

my $input = do { local $/; <STDIN> };
my $array = eval $input;

That string eval is a bit dangerous (and so is Perl's Storable), but that's the idea. Take in some text and unserialize it.

Piping data

You'd then combine those programs in a pipeline:

 $ perl first.pl | perl second.pl

But, you can also print directly to the second program by opening a pipe from the first:

use Data::Dumper;
my @array = qw/1 2 3 4 5/;
open my $pipe, '|-', $^X, $other_program;
print {$pipe} Dumper(\@array);