运行程序§
许多程序需要能够运行其他程序,我们需要向它们传递信息并接收它们的输出和退出状态。在 Raku 中运行程序就像
run 'git', 'status';
这行代码运行名为“git”的程序,并将“git”和“status”传递到它的命令行。它将使用 %*ENV<PATH>
设置找到该程序。
如果您想通过向 shell 发送命令行来运行程序,也有一个工具可以做到这一点。所有 shell 元字符都由 shell 解释,包括管道、重定向、环境变量替换等等。
shell 'ls -lR | gzip -9 > ls-lR.gz';
在使用 shell
处理用户输入时应谨慎。
The Proc
object§
run
和 shell
都返回一个 Proc
对象,它可以用来更详细地与进程通信。请注意,除非您关闭所有输出管道,否则程序通常不会终止。
my = run 'git', 'log', '--oneline', :out;for .out.lines ->.out.close();
如果程序失败(以非零退出代码退出),则在返回的 Proc
对象被下沉时,它将抛出异常。您可以将其保存到一个变量中,即使是匿名变量,以防止下沉
$ = run '/bin/false'; # does not sink the Proc and so does not throw
您可以告诉 Proc
对象通过传递 :out
和 :err
标志将输出捕获为文件句柄。您也可以通过 :in
标志传递输入。
my = run 'echo', 'Hello, world', :out;my = run 'cat', '-n', :in(.out), :out;say .out.get;.out.close();
您还可以使用 Proc
来捕获 PID、向应用程序发送信号并检查退出代码。
my = run 'crontab', '-l';if .exitcode == 0else
The Proc::Async
对象§
当您需要更多地控制与另一个进程的通信时,您将需要使用 Proc::Async
。此类提供对与程序进行异步通信的支持,以及向该程序发送信号的能力。
# Get ready to run the programmy = Proc::Async.new('tail', '-f', '/var/log/system.log');.stdout.tap(-> );.stderr.tap(-> );# Start the programmy = .start;sleep 10;# Tell the program to stop.kill('QUIT');# Wait for the program to finishawait ;
上面的小型程序使用“tail”程序打印名为 system.log
的日志的内容 10 秒,然后告诉程序使用 QUIT 信号停止。
而 Proc
通过 IO::Handle
提供对输出的访问,Proc::Async
通过异步供应(参见 Supply
)提供访问。
如果您想运行一个程序并在等待原始程序完成时做一些工作,start
例程将返回一个 Promise
,该程序在程序退出时保持。
使用 write
方法将数据传递到程序中。