运行程序§

许多程序需要能够运行其他程序,我们需要向它们传递信息并接收它们的输出和退出状态。在 Raku 中运行程序就像

run 'git''status';

这行代码运行名为“git”的程序,并将“git”和“status”传递到它的命令行。它将使用 %*ENV<PATH> 设置找到该程序。

如果您想通过向 shell 发送命令行来运行程序,也有一个工具可以做到这一点。所有 shell 元字符都由 shell 解释,包括管道、重定向、环境变量替换等等。

shell 'ls -lR | gzip -9 > ls-lR.gz';

在使用 shell 处理用户输入时应谨慎。

The Proc object§

runshell 都返回一个 Proc 对象,它可以用来更详细地与进程通信。请注意,除非您关闭所有输出管道,否则程序通常不会终止。

my $git = run 'git''log''--oneline':out;
for $git.out.lines -> $line {
    my ($sha$subject= $line.split: ' '2;
    say "$subject [$sha]";
}
$git.out.close();

如果程序失败(以非零退出代码退出),则在返回的 Proc 对象被下沉时,它将抛出异常。您可以将其保存到一个变量中,即使是匿名变量,以防止下沉

$ = run '/bin/false'# does not sink the Proc and so does not throw

您可以告诉 Proc 对象通过传递 :out:err 标志将输出捕获为文件句柄。您也可以通过 :in 标志传递输入。

my $echo = run 'echo''Hello, world':out;
my $cat  = run 'cat''-n':in($echo.out), :out;
say $cat.out.get;
$cat.out.close();

您还可以使用 Proc 来捕获 PID、向应用程序发送信号并检查退出代码。

my $crontab = run 'crontab''-l';
if $crontab.exitcode == 0 {
    say 'crontab -l ran ok';
}
else {
    say 'something went wrong';
}

The Proc::Async 对象§

当您需要更多地控制与另一个进程的通信时,您将需要使用 Proc::Async。此类提供对与程序进行异步通信的支持,以及向该程序发送信号的能力。

# Get ready to run the program 
my $log = Proc::Async.new('tail''-f',  '/var/log/system.log');
$log.stdout.tap(-> $buf { print $buf });
$log.stderr.tap(-> $buf { $*ERR.print($buf});
 
# Start the program 
my $done = $log.start;
sleep 10;
 
# Tell the program to stop 
$log.kill('QUIT');
 
# Wait for the program to finish 
await $done;

上面的小型程序使用“tail”程序打印名为 system.log 的日志的内容 10 秒,然后告诉程序使用 QUIT 信号停止。

Proc 通过 IO::Handle 提供对输出的访问,Proc::Async 通过异步供应(参见 Supply)提供访问。

如果您想运行一个程序并在等待原始程序完成时做一些工作,start 例程将返回一个 Promise,该程序在程序退出时保持。

使用 write 方法将数据传递到程序中。