使用系统将哈希对象从一个perl脚本传递到另一个脚本

Kom*_*thi 0 perl hash system

我有以下perl脚本,它接受参数'文件并将其存储到哈希中.我想修改并将此哈希传递给我使用system命令调用的另一个perl脚本:

script1.pl

#!/usr/bin/perl -w
# usage perl script1.pl script1.params
# script1.params file looks like this:
# PROJECTNAME=>project_dir
# FASTALIST=>samples_fastq.csv

use Data::Dumper;

my $paramfile = $ARGV[0];

# open parameter file
open PARAM, $paramfile or die print $!;

# save it in a hash
my %param;
while(<PARAM>)
{
        chomp;
        @r = split('=>');
        $param{$r[0]}=$r[1];
}

# define directories
# add to parameters' hash
$param{'INDIR'} = $param{'PROJECTNAME'}.'/input';
$param{'OUTDIR'} = $param{'PROJECTNAME'}.'/output';

.... do something ...
# @samples is a list of sample names
foreach (@samples)
{
        # for each sample, pass the hash values & sample name to a separate script
        system('perl script2.pl <hash> $_');
}
Run Code Online (Sandbox Code Playgroud)

script2.pl

#!/usr/bin/perl -w
use Data::Dumper;
## usage <script2.pl> <hash> <samplename>
# something like getting and printing the hash
my @string = $ARGV[0];
print @string;
Run Code Online (Sandbox Code Playgroud)

如果你可以帮我展示如何传递和获取哈希对象(就像在第二个脚本中打印哈希对象那样简单),那么我将非常感谢你的帮助.

谢谢!

Sob*_*que 6

您正在寻找的是称为序列化的东西.很难直接表示内存结构,以便在进程之间传递它,因为各种有趣的东西,如指针和缓冲区.

因此,您需要将哈希变成简单的东西,以便一次性交出.

我认为有三个关键选项:

  • Storable- perl核心模块,它允许您freezethaw数据结构用于此类目的.
  • JSON - 基于文本的类似哈希结构的表示.
  • XML - 有点像JSON,但有不同的优点/缺点.

您应该使用哪种方法取决于您的数据结构有多大.

Storable 可能是最简单的,但它不会特别便携.

还有Data::Dumper一个选项,因为它打印数据结构.一般来说,我建议上面所有的缺点 - 你仍然需要解析它像JSON/XML,但它也不是可移植的.

示例使用Storable:

use strict;
use warnings;
use Storable qw ( freeze  );
use MIME::Base64;

my %test_hash = (
    "fish"   => "paste",
    "apples" => "pears"
);

my $frozen = encode_base64 freeze( \%test_hash );

system( "perl", "some_other_script.pl", $frozen );
Run Code Online (Sandbox Code Playgroud)

呼叫:

use strict;
use warnings;
use Storable qw ( thaw );
use Data::Dumper;
use MIME::Base64;

my ($imported_scalar) = @ARGV; 
print $imported_scalar;
my $thing =  thaw (decode_base64 $imported_scalar ) ;
print Dumper $thing;
Run Code Online (Sandbox Code Playgroud)

要么:

my %param =  %{ thaw (decode_base64 $imported_scalar ) };
print Dumper \%param;
Run Code Online (Sandbox Code Playgroud)

这将打印:

BAoIMTIzNDU2NzgEBAQIAwIAAAAKBXBhc3RlBAAAAGZpc2gKBXBlYXJzBgAAAGFwcGxlcw==
$VAR1 = {
          'apples' => 'pears',
          'fish' => 'paste'
        };
Run Code Online (Sandbox Code Playgroud)

做同样JSON的事情 - 它具有以纯文本形式传递的优点,并且具有通用格式.(大多数语言都可以解析JSON):

#!/usr/bin/env perl
use strict;
use warnings;
use JSON; 

my %test_hash = (
    "fish"   => "paste",
    "apples" => "pears"
);
my $json_text = encode_json ( \%test_hash );
print "Encoded: ",$json_text,"\n";

system( "perl", "some_other_script.pl", quotemeta $json_text );
Run Code Online (Sandbox Code Playgroud)

呼叫:

#!/usr/bin/env perl
use strict;
use warnings;
use JSON;
use Data::Dumper;

my ($imported_scalar) = @ARGV; 
$imported_scalar =~ s,\\,,g;
print "Got: ",$imported_scalar,"\n";

my $thing =  decode_json $imported_scalar ;

print Dumper $thing;
Run Code Online (Sandbox Code Playgroud)

不幸的是,需要quotemeta和删除斜杠,因为shell会插入它们.如果您正在尝试执行此类操作,这是常见问题.