0

我使用 Perl 脚本来配置和生成一个已编译的程序,该程序需要以某种方式配置的子 shell,所以我使用$returncode = system("ulimit -s unlimited; sg ourgroup 'MyExecutable.exe'");

我想从中捕获并解析 STDOUT,但我需要将它分叉,以便在作业仍在运行时检查输出。这个问题很接近: 如何将 Perl 输出发送到 STDOUT 和变量?评分最高的答案描述了一个名为的函数,该函数backtick()创建一个子进程,捕获STDOUT并在其中运行命令exec()

但是我的调用需要多行来配置 shell。一种解决方案是创建一个一次性的 shell 脚本:

#disposable.sh
    #!/bin/sh
    ulimit -s 无限
    sg ourgroup 'MyExecutable.exe'

然后我可以用backtick(disposable.sh)或得到我需要的东西open(PROCESS,'disposable.sh|')

但我真的不想为此制作一个临时文件。system()愉快地接受多行命令字符串。我怎样才能得到exec()open()做同样的事情?

4

3 回答 3

1

如果您想使用 shell 的强大功能(包括循环、变量,还包括多个命令执行),您必须调用 shell(open(..., 'xxx|')不这样做)。

您可以使用 shell-c选项将 shell 脚本传递给 shell(另一种可能性是将命令通过管道传送到 shell,但恕我直言,这更难)。这意味着backtick从另一个答案调用函数,如下所示:

backtick("sh", "-c", "ulimit -s unlimited; sg ourgroup 'MyExecutable.exe'");
于 2013-04-10T19:07:27.530 回答
0

与程序 交互时应使用 Expect :http: //metacpan.org/pod/Expect 假设您的 *nix 上的 /bin/bash 与bash-3.2$之类的内容匹配,则以下程序可用于启动命令数量在 bash 控制台上使用 $exp->send,然后可以解析每个命令的输出以进行进一步的操作。

#!/usr/bin/perl
use Expect;
my $command="/bin/bash";
my @parameters;
my $exp= new Expect;
$exp->raw_pty(1);
$exp->spawn($command);
$exp->expect(5, '-re', 'bash.*$');
$exp->send("who \n");
$exp->expect(10, '-re', 'bash.*$');
my @output = $exp->before(); 
print "Output of who command is @output \n";
$exp->send("ls -lt \n");
$exp->expect(10, '-re', 'bash.*$');
my @output = $exp->before(); 
print "Output of ls command is @output \n";
于 2013-04-10T19:23:08.923 回答
0

带有反引号的系统tee会这样做,不是吗?

my $output = `(ulimit -s unlimited; sg ourgroup 'MyExecutable.exe') | tee /dev/tty`;

或修改 Alnitak 的backticks(所以它确实使用了子外壳)?

my $cmd = "ulimit -s unlimiited ; sg ourgroup 'MyExecutable.exe'";
my $pid = open(CMD, "($cmd) |");
my $output;
while (<CMD>) {
   print STDOUT $_;
   $output .= $_;
}
close CMD;
于 2013-04-11T05:17:34.703 回答