How to read values assigned inside a script, in a program that runs that script?

六月ゝ 毕业季﹏ 提交于 2020-06-16 03:33:30

问题


I need some help with reading value assigned inside sub scripts executed within main script in perl

  1. I have "main.pl" where i have few hashes (%var1 %var2) declared and assigned and am processing the values throughout the script.
  2. Within main.pl, i execute a perl script "sub_scirpt.pl" using system(perl sub_script.pl)
  3. Inside sub.pl, if i am assigning few value to %var1 %var2
  4. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!