如何从另一个脚本执行脚本,以便它还为调用者脚本

时间:2018-02-28 18:54:43

标签: perl

我在线查看了很多关于运行另一个进程(PERL或shell命令或程序)的示例,但是找不到任何有用的方法。

(正如已经收到的答案,我看到我的请求'不被理解,我会试着简短地说,留下所有早期印刷作为我已经尝试过的例子......)

我需要:
  - 在调用第二个脚本之前,在调用者脚本中设置第二个脚本的参数(因此,我无法使用它在启动之前执行的do script2.pl来运行第一个脚本)
  - 在第二个脚本中,我需要设置一些将在调用者脚本中使用的变量(因此,system()back ticks处理第二个脚本没有用;)
  - 并且,因为我需要在第一个脚本中使用这些变量,所以在完成第二个脚本之后我需要回到第一个脚本 (我希望现在更清楚我需要什么...)

(已审核且无用system()'back ticks'exec()open()

我想从第一个开始运行另一个PERL脚本,而不是退出(如exec()所示),而不是捕获被调用脚本的STDOUT(如back tick中所示处理,但打印出来,如初始脚本(由system()),而我不需要返回状态(如system());

  • 但是,我想让被调用的脚本设置一些变量,这些变量可以在调用s cript中访问(当然,由our @set_var设置;)

我的尝试(我无法做出我需要做的事)是:

Script1就像是:

...
 if($condition) 
{  local $0 = 'script2.pl';
    local @ARGV = ('first-arg', 'second_arg');
    do script2.pl;
}
print "set array is: '@set_var'\n";
...

' script2'会有类似的东西:

#!/usr/bin/perl
...
  print "having input parameters: '@ARGV'\n";
  ... # all script activities
  our @set_var = ($val1, $val2, $val3);
  exit 0;

我的代码中的问题是do ...命令在第一个脚本运行开始时执行,并且不在它准备好的地方(通过设置一些local ..变量! )

我确实尝试使用eval "do script2.pl": - 现在它在适当的位置执行,但它没有将@set_var设置为第一个脚本进程!

有什么想法,我想拥有它吗? (我明白,我可以重写script2.pl,包括一些函数中的整个处理(比如main())并加载require()并执行函数main():这样做我喜欢它的所有内容;但是我希望将第二个脚本保留为原来可以从shell中执行,就像现在一样。
 ...而且我不喜欢通过平面文件传递值的方法......)

有人知道如何做我的心血来潮吗?

3 个答案:

答案 0 :(得分:3)

这很好用:

script2.pl

use strict;
our @set_var = ("foo","bar");

script1.pl

use strict;
our @set_var;
do './script2.pl';
print "@set_var\n";
$ perl script1.pl
foo bar

但是如果你使用的话就没有:

script2.pl

use strict;
our @set_var = ("foo","bar");
exit 0;

此示例中只有一个perl进程,因此即使从第二个脚本调用exit,也会退出程序。

如果您不想在第二个脚本中删除exit调用,我们可以解决一些CORE::GLOBAL命名空间黑客攻击问题。要点是将exit函数重定向到您自己的自定义函数,您可以在第二个脚本运行时进行操作。

script1.pl

BEGIN { *CORE::GLOBAL::exit = *my_exit };
use strict;
sub my_exit { goto &CORE::exit }
our @set_var;
{
    local *my_exit = sub { warn "Not exiting" };
    do './script2.pl';
}
print "@set_var\n";

script2.pl

use strict;
our @set_var = ("foo","bar");
exit 0;

$ perl script1.pl
Not exiting at script1.pl line 7.
foo bar

答案 1 :(得分:0)

(好吧,最后,我自己也问过,自己也回答!)  (经过额外的审核,我意识到,' mod' 解决方案确实使用了它,但我不明白建议!
  对不起:我错过了真正的解决方案!

解决我的问题很简单!它是:

  

做EXPR;

那样的方式   - 第二个脚本在它放置的位置执行;所以,在第一个中定义和设置的任何东西都在第二个中有用;
  - 正在向STDOUT打印应该打印的所有内容(第二个脚本;)
  - 在第二个脚本过程中定义的任何变量或对象,在返回后可在第一个中访问;和
  - 在第二个脚本执行后立即将控制返回到位置,并继续处理第一个脚本命令!

简单!我很惊讶,为什么我忘了这一点'做...'命令。我已经使用过它了一次!

我对那个论坛感到很失望!  虽然它的设计非常糟糕,但是参与者,而不是perl-issue审查,非常关心调节他人,教他们如何离开这样一个好的论坛!

答案 2 :(得分:-1)

我不确定你要做的是什么,但是沿着这些方向它应该非常接近。

test.pl

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

use IPC::System::Simple qw(system);

say $0;
system($^X, "sample.pl", @ARGV);
$ perl test.pl first-arg second-arg
test.pl
sample.pl
$VAR1 = [
          'first-arg',
          'second-arg'
        ];

sample.pl

#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

use feature 'say';

say $0;
print Dumper \@ARGV;

我使用了模块IPC::System::Simple。您还可以通过IPC::System::Simple::capture捕获脚本的输出(sample.pl)。

更新:也许您可以使用Storable。这样,您可以将可以在脚本2(sample.pl)中使用的新参数传递给脚本1(test.pl)。

<强> test.pl

#!/usr/bin/perl
use strict;
use warnings;
use Storable;
use Data::Dumper;
use feature 'say';
use IPC::System::Simple qw(system);

say $0;
system($^X, "sample.pl", @ARGV);

my $hashref = retrieve('sample');
print Dumper $hashref;

__END__

$ perl test.pl first-arg second-arg
test.pl
sample.pl
$VAR1 = [
          'first-arg',
          'second-arg'
        ];
$VAR1 = {
          'arg1' => 'test1',
          'arg2' => 'test2'
        };

<强> sample.pl

#!/usr/bin/perl
use strict;
use warnings;
use Storable;
use Data::Dumper;
use feature 'say';

say $0;
print Dumper \@ARGV;

my %hashArgs = ( arg1 => 'test1',
         arg2 => 'test2', );

store \%hashArgs, 'sample';