0

我对从另一个脚本调用脚本的各种方法有些熟悉。我真的不需要对每一个进行概述,但我确实有几个问题。不过,在那之前,我应该告诉你我的目标是什么。

我正在开发一个 perl/tk 程序,该程序:a) 收集信息并将其放入散列中,b) 触发其他使用 info 散列和一些命令行参数的脚本。这些其他脚本中的每一个都在命令行上可用(使用另一个命令行脚本)并且需要保持这种方式。所以我不能把所有的东西都放在一个模块中并称其为好。我确实有权更改脚本,但同样,它们也必须在命令行上可用。

当前调用另一个脚本的方法是使用'do',这意味着我可以传入哈希,并使用相同版本的perl(我认为)。但是所有的 STDOUT(我认为还有 STDERR)都进入了终端。

这是一个演示输出的简单示例:

this_thing.pl
#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use Tk;
my $mw = MainWindow->new; 
my $button = $mw->Button( 
    -text => 'start other thing', 
    -command => \&start, 
)->pack; 
my $text = $mw->Text()->pack; 
MainLoop; 

sub start { 
    my $script_path = 'this_other_thing.pl'; 
    if (not my $read = do $script_path) {  
        warn "couldn't parse $script_path: $@" if $@; 
        warn "couldn't do $script_path: $!" unless defined $read; 
        warn "couldn't run $script_path" unless $read; 
    } 
} 

this_other_thing.pl 
#!/usr/bin/env perl 
use strict; 
use warnings; 
use utf8; 

print "Hello World!\n";

如何使用“do”方法将 STDOUT 和 STDIN(对于需要输入的交互式脚本)重定向到文本框?这甚至可能吗?

如果我不能使用 'do' 方法,什么方法可以重定向 STDIN 和 STDOUT,以及启用传递哈希并使用相同版本的 perl?

编辑:我在 Perlmonks 的第一条评论中的链接上发布了同样的问题。到目前为止,最好的反应似乎是使用模块并且让子脚本只是模块的包装器。其他可能的解决方案是:ICP::Run(3) 和一般的 ICP、Capture::Tiny 和相关模块以及 Tk::Filehandle。提出了一种重定向输出和错误流的解决方案,但似乎不影响输入流。它也有点笨拙,不推荐。

编辑2:我在这里发布这个是因为我还不能回答我自己的问题。感谢您的建议和建议。我提出了关于 Perlmonks 的建议。建议是将子脚本转换为模块,并在它们周围使用包装器脚本以供正常使用。然后我就可以简单地使用这些模块,所有代码都在一个地方。这也确保了我没有使用不同的 perls,我可以将模块的输出路由到我想要的任何地方,并且现在传递该哈希非常容易。

4

1 回答 1

0

要重定向子进程的 STDIN 和 STDOUT,您应该阅读 perlipc 手册页的“与另一个进程的双向通信”部分:http ://search.cpan.org/~rjbs/perl-5.18.1/pod/ perlipc.pod#Bidirectional_Communication_with_Another_Process

使用相同版本的 perl 可以通过找出你的 perl 解释器的名称并显式调用它来工作。$^X 可能是你想要的。它可能适用于也可能不适用于不同的操作系统。

将哈希传递给子进程并不容易。您可以将哈希的内容打印到文件中,并让子进程读取并解析它。您可能会在不使用文件的情况下通过在两个进程之间使用 STDIN 通道而逃脱,或者您可以为此目的打开一个单独的 pipe()。无论如何,使用子进程时无法避免打印和解析数据,因为这两个进程使用两个 perl 解释器,每个都有自己的内存空间,并且无法看到彼此的变量。

您可以通过使用 fork() + eval() + require() 来避免使用子进程。在这种情况下,不会涉及单独的 perl 解释器,分叉的解释器将继承程序的整个内存,其中包含所有变量、打开的文件描述符、套接字等,包括要传递的哈希。但是,从 CLI 启动时,我看不到您的第二个 perl 脚本可以从哪里获取其哈希值。

于 2013-10-01T16:15:32.427 回答