将一个散列对象从一个perl脚本传递给另一个使用系统 [英] Pass a hash object from one perl script to another using system

查看:119
本文介绍了将一个散列对象从一个perl脚本传递给另一个使用系统的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下perl脚本,它接受参数文件并将其存储到散列中。我想修改&将这个散列传递给另一个使用系统命令调用的perl脚本:



script1.pl

<$ p $使用perl script1.pl script1.params
#script1.params文件如下所示:
#PROJECTNAME => project_dir
#FASTALIST => samples_fastq.csv

use Data :: Dumper;

my $ paramfile = $ ARGV [0];

#打开参数文件
打开PARAM,$ paramfile或die print $ !;

#将它保存为一个散列
my%param; $(< PARAM>)
{
chomp;
@r = split('=>');
$ param {$ r [0]} = $ r [1];
}

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

...做某事...
#@samples是一个样本名称列表
foreach(@samples)
{
#for每个样本,通过散列值&样本名称到单独的脚本
system('perl script2.pl< hash> $ _');
}

script2.pl

 #!/ usr / bin / perl -w 
使用Data :: Dumper;
## usage< script2.pl> <散列> < samplename>
#就像获取和打印散列
my @string = $ ARGV [0];
print @string;

如果您可以帮助我展示如何传递和获取散列对象(像打印散列对象在第二个脚本会做),那么我会感谢您的帮助。

谢谢!

解决方案

你在找什么叫做序列化。由于各种有趣的事情,比如指针和缓冲区,直接表示内存结构的方式很难直接在进程之间传递。



所以你需要把你的哈希变成足够简单的东西,以便一次性交出。



在我看来,这有三个关键选项:


  • 可存储 - perl核心模块,可让您冻结解冻这种目的的数据结构。

  • JSON - 一种类似散列结构的基于文本的表示形式。

  • <$



你是哪一个人应该使用取决于你的数据结构有多大。

可存储可能是最简单的,但它不会特别便携。

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







$ b $ 使用strict;
使用警告;
使用Stable qw(冻结);
使用MIME :: Base64;

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

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

系统(perl,some_other_script.pl,$ frozen);

调用:

 使用strict; 
使用警告;
使用Stable qw(解冻);
使用Data :: Dumper;
使用MIME :: Base64;

my($ imported_scalar)= @ARGV;
print $ imported_scalar;
my $ thing = thaw(decode_base64 $ imported_scalar);
打印Dumper $ thing;

或者:

  my%param =%{thaw(decode_base64 $ imported_scalar)}; 
打印Dumper \%param;

这将打印:

  BAoIMTIzNDU2NzgEBAQIAwIAAAAKBXBhc3RlBAAAAGZpc2gKBXBlYXJzBgAAAGFwcGxlcw == 
$ VAR1 = {
'apples'=> '梨',
'fish'=> '贴'
};

JSON 做同样的处理 - 以纯文本形式传递的优点,以及通用格式。 (大多数语言可以解析 JSON ):
$ b

 #!/ usr / bin / env perl 
使用strict;
使用警告;
使用JSON;

my%test_hash =(
fish=>paste,
apples=>pear
);
my $ json_text = encode_json(\%test_hash);
printEncoded:,$ json_text,\\\
;

system(perl,some_other_script.pl,quotemeta $ json_text);

调用:

 #!/ usr / bin / env perl 
use strict;
使用警告;
使用JSON;
使用Data :: Dumper;

my($ imported_scalar)= @ARGV;
$ imported_scalar =〜s,\\ ,, g;
打印Got:,$ imported_scalar,\\\
;

my $ thing = decode_json $ imported_scalar;

打印Dumper $ thing;

不幸的是,需要quotemeta和删除斜杠,因为shell将它们插值。如果你想要做这种事,这是常见的问题。

I have the following perl script, that takes in a parameters' file and stores it into a hash. I want to modify & pass this hash to another perl script that I am calling using the system command:

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> $_');
}

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;

If you can help me showing how to pass and get the hash object (something simple like printing the hash object in the second script would do), then I'd appreciate your help.

Thanks!

解决方案

What you're looking for is something called serialisation. It's difficult to directly represent a memory structure in such a way as to pass it between processes, because of all sorts of fun things like pointers and buffers.

So you need to turn your hash into something simple enough to hand over in a single go.

Three key options for this in my opinion:

  • Storable - a perl core module that lets you freeze and thaw a data structure for this sort of purpose.
  • JSON - a text based representation of a hash-like structure.
  • XML - bit like JSON, but with slightly different strengths/weaknesses.

Which you should use depends a little on how big your data structure is.

Storable is probably the simplest, but it's not going to be particularly portable.

There's also Data::Dumper that's an option too, as it prints data structures. Generally though, I'd suggest that has all the downsides of all the above - you still need to parse it like JSON/XML but it's also not portable.

Example using 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 );

Calling:

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;

Or:

my %param =  %{ thaw (decode_base64 $imported_scalar ) };
print Dumper \%param;

This will print:

BAoIMTIzNDU2NzgEBAQIAwIAAAAKBXBhc3RlBAAAAGZpc2gKBXBlYXJzBgAAAGFwcGxlcw==
$VAR1 = {
          'apples' => 'pears',
          'fish' => 'paste'
        };

Doing the same with JSON - which has the advantage of being passed as plain text, and in a general purpose format. (Most languages can parse 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 );

Calling:

#!/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;

Need the quotemeta and the removal of slashes unfortunately, because the shell interpolates them. This is the common problem if you're trying to do this sort of thing.

这篇关于将一个散列对象从一个perl脚本传递给另一个使用系统的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆