问题
I need some help with reading value assigned inside sub scripts executed within main script in perl
- I have "main.pl" where i have few hashes (
%var1
%var2
) declared and assigned and am processing the values throughout the script. - Within main.pl, i execute a perl script "sub_scirpt.pl" using
system(perl sub_script.pl)
- Inside sub.pl, if i am assigning few value to
%var1
%var2
- How do i print the values assigned in sub_script.pl of
%var1
at main.pl script level?
Hope the above description gives some picture on my requirement.
content of sub_script.pl
our %var1 ;
our $var1 = "start";
our $var2 = "abcd";
our $var3 = "efgh";
our @var4 = qw{test1 test2 test3};
$var1{$var2}{$var3}->{test1} = "1234";
$var1{$var2}{$var3}->{test2} = "5679";
$var1{$var2}{$var3}->{test3} = "5555";
foreach $var (@var4) {
print "sub_script:: var1: $var1 \nsub_script:: var2: $var2 \nsub_script:: var3: $var3 \nsub_script:: var4: $var \nsub_script:: hash-value: $var1{$var2}{$var3}->{$var}\n";
}
Output of sub_script.pl:
sub_script:: var1: start
sub_script:: var2: abcd
sub_script:: var3: efgh
sub_script:: var4: test1
sub_script:: hash-value: 1234
sub_script:: var1: start
sub_script:: var2: abcd
sub_script:: var3: efgh
sub_script:: var4: test2
sub_script:: hash-value: 5679
sub_script:: var1: start
sub_script:: var2: abcd
sub_script:: var3: efgh
sub_script:: var4: test3
sub_script:: hash-value: 5555
content of main.pl
@var1 = qw{start end};
$var1 = @var1[1];
our $var2 = "abcd";
our $var3 = "efgh";
@var4 = qw{test1 test2 test3};
system ("perl sub_script.pl");
print "\n\n";
foreach $var (@var4) {
print "main:: var1: $var1 \nmain:: var2: $var2 \nmain:: var3: $var3 \nmain:: var4: $var \nmain::hash-value:$var1{$var2}{$var3}->{$var}\n";
}
Output of main.pl:
main:: var1: end main:: var2: abcd main:: var3: efgh main:: var4: test1 main:: hash-value: main:: var1: end main:: var2: abcd main:: var3: efgh main:: var4: test2 main:: hash-value: main:: var1: end main:: var2: abcd main:: var3: efgh main:: var4: test3 main:: hash-value:
Intended output:
main:: var1: start main:: var2: abcd main:: var3: efgh main:: var4: test1 main:: hash-value: 1234 main:: var1: start main:: var2: abcd main:: var3: efgh main:: var4: test2 main:: hash-value: 5679 main:: var1: start main:: var2: abcd main:: var3: efgh main:: var4: test3 main:: hash-value: 5555
-Thanks in advance
回答1:
In short, you need to pass data from a program back to the program that invoked it.
If the called program (sub_script.pl
) needs to return only simple values then it can just print them to STDOUT
, where the calling program (main.pl
) runs it via "backticks" (qx in the operator form), which returns the program's STDOUT
.
However, more complex data structures need be serialized so that they can be meaningfully sent down a pipe (of some kind) byte by byte. There are various ways to do so, with good libraries, and simple code below demonstrates two of them.
The JSON format is very simple, human readable, and accessible from any language and system. Perl libraries for conversion between Perl data structures and corresponding JSON are very simple to use. This is a good and safe solution for a wide range of situations.
Perl's Storable is a tool for persistency, so that complex data structures can be dumped to disk and later restored from the file. One can also serialize data to strings that can be passed between programs with no need for files.
The program sub_script.pl below creates a hash and makes a JSON
string out of it and prints it, and then also serializes the hash into a Storable
string which it also prints
use warnings;
use strict;
use feature 'say';
use JSON;
use Storable qw(nfreeze);
my %h = (a => { A => 1}, b => { B => 2 });
my $str_json = encode_json \%h;
say $str_json;
my $str_st = nfreeze \%h;
say $str_st;
The following program (main.pl) runs the sub_script.pl
above using qx
so that it receives its STDOUT
, and then it rebuilds the hash from both the JSON
and Storable
strings. In both cases we get back a hashref, a reference to data like the original hash
use warnings;
use strict;
use feature 'say';
use JSON;
use Storable qw(thaw);
use Data::Dump qw(dd);
my @ret = qx( sub_script.pl );
chomp @ret;
my $hr1 = decode_json $ret[0];
dd $hr1;
my $hr2 = thaw $ret[1];
dd $hr2;
I use JSON for simplicity, which will use the fast JSON_XS
if installed, or the pure-Perl fallback, the core JSON_PP
. Another option is Cpanel::JSON::XS, a fork of JSON_XS
.
To print complex data structures so to see them easily I use Data::Dump, which probably need be installed. There is a number of other good modules to show complex data, the most widely used one being the core Data::Dumper (so no need to install).
In all of this, the program that is called still just prints to its STDOUT
. When data exchange needs get more complex you may need to use some "Inter-Process-Communication" (IPC) techniques.
来源:https://stackoverflow.com/questions/62230087/how-to-read-values-assigned-inside-a-script-in-a-program-that-runs-that-script