Proc::Async
允许您异步运行外部命令,捕获标准输出和错误句柄,并可以选择写入其标准输入。
my = ‘foo’.IO;spurt , “and\nCamelia\n♡\nme\n”;my = Proc::Async.new: :w, ‘tac’, ‘--’, , ‘-’;# my $proc = Proc::Async.new: :w, ‘sleep’, 15; # uncomment to try timeoutsreactsay ‘Program finished’;
上面的示例生成以下输出
line: me line: ♡ line: Camelia line: and line: Camelia line: ♥ line: I Proc finished. Exit code: 0 Program finished
或者,您可以使用 Proc::Async
,而无需使用 react 块
# command with argumentsmy = Proc::Async.new('echo', 'foo', 'bar');# subscribe to new output from out and err handles:.stdout.tap(-> , quit => );.stderr.tap(-> );say "Starting...";my = .start;# wait for the external program to terminateawait ;say "Done.";
这会产生以下输出
Starting... Output: foo bar Done.
打开外部程序进行写入的示例
my = Proc::Async.new(:w, 'hexdump', '-C');my = .start;await .write(Buf.new(12, 42));.close-stdin;await ;
管道多个命令的示例,如 echo "Hello, world" | cat -n
my = Proc::Async.new: 'echo', 'Hello, world';my = Proc::Async.new: 'cat', '-n';.bind-stdin: .stdout;await .start, .start;
方法§
方法 new§
multi method new(*@ (, *), :, :, :, :,: = False,: = False --> Proc::Async)multi method new( :, :, :, :, :, :,: = False,: = False --> Proc::Async)
使用外部程序名称或路径 $path
和命令行参数 @args
创建一个新的 Proc::Async
对象。
如果 :w
传递给 new
,则会打开一个管道到外部程序的标准输入流(stdin
),您可以使用 write
和 say
向其写入。
:enc
指定流的 编码(仍可以在各个方法中覆盖),默认为 utf8
。
如果 :translate-nl
设置为 True
(默认值),则特定于操作系统的换行符(例如 Windows 上的 \r\n
)将自动转换为 \n
。
如果 :arg0
设置为一个值,则该值将作为 arg0 传递给进程,而不是程序名称。
:started
属性默认设置为 False
,因此您需要使用 .start
在之后启动命令。如果您想绑定任何处理程序,则可能不想这样做,但如果您只需要立即启动外部程序,则没有问题。
在 Windows 上,标志 $win-verbatim-args
禁用所有进程参数的自动引用。有关 Windows 命令引用的更多信息,请参阅 此博客。在所有其他平台上忽略该标志。该标志在 Rakudo 版本 2020.06 中引入,在较旧版本中不存在。默认情况下,它设置为 False
,在这种情况下,参数将根据 Microsoft 惯例进行引用。
方法 stdout§
method stdout(Proc::Async: : --> Supply)
返回外部程序的标准输出流的 Supply
。如果传递了 :bin
,则标准输出将作为 Blob
以二进制形式传递,否则将解释为 UTF-8,解码并作为 Str
传递。
my = Proc::Async.new(:r, 'echo', 'Raku');.stdout.tap( ->);my = .start;await ;
在调用 .start
之前,必须调用 stdout
。否则将抛出 X::Proc::Async::TapBeforeSpawn
类的异常。
如果未调用 stdout
,则根本不会捕获外部程序的标准输出。
请注意,不能在同一对象上同时使用和不使用 :bin
调用 stdout
;如果尝试这样做,它将抛出 X::Proc::Async::CharsOrBytes
类型的异常。
对于合并的 STDOUT 和 STDERR,请使用 .Supply
。
方法 stderr§
method stderr(Proc::Async: : --> Supply)
返回外部程序的标准错误流的 Supply
。如果传递了 :bin
,则标准错误将作为 Blob
以二进制形式传递,否则将解释为 UTF-8,解码并作为 Str
传递。
my = Proc::Async.new(:r, 'echo', 'Raku');.stderr.tap( ->);my = .start;await ;
在调用 .start
之前,必须调用 stderr
。否则将抛出 X::Proc::Async::TapBeforeSpawn
类的异常。
如果未调用 stderr
,则根本不会捕获外部程序的标准错误流。
请注意,不能在同一对象上同时使用和不使用 :bin
调用 stderr
;如果尝试这样做,它将抛出 X::Proc::Async::CharsOrBytes
类型的异常。
对于合并的 STDOUT 和 STDERR,请使用 .Supply
。
方法 bind-stdin§
multi method bind-stdin(IO::Handle )multi method bind-stdin(Proc::Async::Pipe )
将句柄(必须打开)或 Pipe
设置为 STDIN
的源。目标进程的 STDIN
必须可写,否则将抛出 X::Proc::Async::BindOrUse
。
my = Proc::Async.new("cat", :in);my = "/etc/profile".IO.open;.bind-stdin();.start;
这等同于
cat < /etc/profile
并将 /etc/profile
的内容打印到标准输出。
方法 bind-stdout§
method bind-stdout(IO::Handle )
将目标进程的 STDOUT 重定向到句柄(必须打开)。如果 STDOUT 已关闭,则将抛出 X::Proc::Async::BindOrUse
。
my = Proc::Async.new("ls", :out);my = "ls.out".IO.open(:w);.bind-stdout();.start;
此程序将 ls
shell 命令的输出通过管道传输到名为 ls.out
的文件,该文件已打开以供读取。
方法 bind-stderr§
method bind-stderr(IO::Handle )
将目标进程的 STDERR
重定向到句柄(必须打开)。如果 STDERR
已关闭,则将抛出 X::Proc::Async::BindOrUse
。
my = Proc::Async.new("ls", "--foo", :err);my = "ls.err".IO.open(:w);.bind-stderr();.start;
方法 w§
method w(Proc::Async:)
如果将 :w
传递给构造函数,即如果外部程序以其输入流启动,则该流可通过 .print
、.say
和 .write
方法输出到程序,则返回真值。
方法 start§
method start(Proc::Async: : = , :, : = --> Promise)
启动外部程序的生成。返回一个 Promise
,该程序将在外部程序退出后使用 Proc
对象保留,如果无法启动程序,则会中断。或者,你可以使用调度程序代替默认的 $*SCHEDULER
,或通过命名参数 :$ENV
更改进程运行的环境,或通过命名参数 :$cwd
更改目录。
如果在 Proc::Async 对象上调用 start
,而之前已经调用过它,则会抛出类型为 X::Proc::Async::AlreadyStarted
的异常。
注意:如果你希望 await
Promise 并丢弃其结果,则使用
try await .start;
将抛出如果程序以非零状态退出,因为作为 Promise 结果返回的 Proc
在下沉时抛出,在这种情况下,它将在 try
外部下沉。为了避免这种情况,请在 try
内部 自行下沉
try sink await .start;
方法 started§
method started(Proc::Async: --> Bool)
在调用 .start
之前返回 False
,之后返回 True
。
方法 ready§
method ready(Proc::Async: --> Promise)
返回一个 Promise
,该程序将在进程成功启动后保留。如果程序无法启动,则 Promise
将中断。
特定于实现的注释:从 Rakudo 2018.04 开始,返回的 promise 将保存进程 ID (PID)。
方法 pid§
method pid(Proc::Async: --> Promise)
等同于 ready。
返回一个 Promise
,该程序将在进程成功启动后保留。如果程序无法启动,则 Promise
将中断。返回的 promise 将保存进程 ID (PID)。
特定于实现的注释:从 Rakudo 2018.04 开始可用。
方法 path§
method path(Proc::Async:)
已弃用,v6.d 起。请改用 command。
返回作为第一个参数传递给 new
方法的外部程序的名称和/或路径。
方法 args§
method args(Proc::Async: --> Positional)
已弃用,v6.d 起。请改用 command。
返回外部程序的命令行参数,如传递给 new
方法。
方法 command§
method command(Proc::Async: --> List)
从 v6.d 起可用。
返回用于此 Proc::Async
对象的命令和参数
my := Proc::Async.new: 'cat', 'some', 'files';.command.say; # OUTPUT: «(cat some files)»
方法 write§
method write(Proc::Async: Blob , : = --> Promise)
将 $b
中的二进制数据写入外部程序的标准输入流。
返回一个Promise
,该 Promise 将在数据完全进入外部程序的输入缓冲区后被保留。
必须为写入创建Proc::Async
对象(使用Proc::Async.new(:w, $path, @args)
)。否则,将抛出X::Proc::Async::OpenForWriting
异常。
在调用方法 write 之前必须调用start
,否则将抛出X::Proc::Async::MustBeStarted
异常。
方法 print§
method print(Proc::Async: Str() , : = )
将$str
中的文本数据写入外部程序的标准输入流,并将其编码为 UTF-8。
返回一个Promise
,该 Promise 将在数据完全进入外部程序的输入缓冲区后被保留。
必须为写入创建Proc::Async
对象(使用Proc::Async.new(:w, $path, @args)
)。否则,将抛出X::Proc::Async::OpenForWriting
异常。
在调用方法 print 之前必须调用start
,否则将抛出X::Proc::Async::MustBeStarted
异常。
方法 put§
method put(Proc::Async: \x, |c)
对输出执行.join
,添加一个换行符,并对其调用.print
。如果未启动或未打开以进行写入,则会抛出异常。
方法 say§
method say(Proc::Async: , : = )
对$output
调用方法gist
,添加一个换行符,将其编码为 UTF-8,并将其发送到外部程序的标准输入流,并将其编码为 UTF-8。
返回一个Promise
,该 Promise 将在数据完全进入外部程序的输入缓冲区后被保留。
必须为写入创建Proc::Async
对象(使用Proc::Async.new(:w, $path, @args)
)。否则,将抛出X::Proc::Async::OpenForWriting
异常。
在调用方法 say 之前必须调用start
,否则将抛出X::Proc::Async::MustBeStarted
异常。
方法 Supply§
multi method Supply(Proc::Async: :!)multi method Supply(Proc::Async: :, :)
返回合并的stdout和stderr流的Supply
。如果提供了:$bin
命名参数,则Supply
将是二进制的,生成Buf
对象;否则,它将处于字符模式,生成Str
对象,并且:$enc
命名参数可以指定要使用的编码。:$translate-nl
选项指定是否应转换新行结尾以匹配当前操作系统使用的结尾(例如,Windows 上的\r\n
)。
react
创建二进制和非二进制.Supply
是错误的。同时使用.Supply
和stderr或stdout供应也是错误的。
方法 close-stdin§
method close-stdin(Proc::Async: --> True)
关闭外部程序的标准输入流。从 STDIN 读取的程序通常只有在其输入流关闭时才会终止。因此,如果等待来自.start
的 Promise 挂起(对于为写入打开的程序),则可能是忘记了close-stdin
。
必须为写入创建Proc::Async
对象(使用Proc::Async.new(:w, $path, @args)
)。否则,将抛出X::Proc::Async::OpenForWriting
异常。
在调用方法 close-stdin 之前必须调用start
,否则将抛出X::Proc::Async::MustBeStarted
异常。
方法 kill§
multi method kill(Proc::Async: Signal \signal = SIGHUP)
multi method kill(Proc::Async: Int \signal)
multi method kill(Proc::Async: Str \signal)
向正在运行的程序发送信号。该信号可以是信号名称(“KILL”或“SIGKILL”)、整数(9)或Signal
枚举的元素(Signal::SIGKILL);默认情况下,如果没有参数,将使用SIGHUP
信号。