pub struct Command { /* private fields */ }展开描述
该结构体模仿 std::process::Command 标准库中的 API,
但将创建进程的相关函数替换为异步版本。提供的主要异步函数有
spawn、status 和
output。
Command 使用了一些 std 类型的异步版本(例如 Child)。
实现§
Source§impl Command
impl Command
Sourcepub fn new<S: AsRef<OsStr>>(program: S) -> Command
pub fn new<S: AsRef<OsStr>>(program: S) -> Command
构造一个用于启动位于路径 program 处程序的新 Command,
采用如下默认配置:
- No arguments to the program
- Inherit the current process’s environment
- Inherit the current process’s working directory
- Inherit stdin/stdout/stderr for
spawnorstatus, but create pipes foroutput
提供了一些 builder 方法以修改这些默认设置并对进程进行其它配置。
如果 program 不是绝对路径,将以操作系统定义的方式搜索 PATH。
要使用的搜索路径可以通过在 Command 上设置 PATH 环境变量来控制,
但在 Windows 上存在一些实现限制
(参见 issue rust-lang/rust#37519)。
§示例
基本用法:
use tokio::process::Command;
let mut command = Command::new("sh");Sourcepub fn as_std(&self) -> &StdCommand
pub fn as_std(&self) -> &StdCommand
廉价地转换为一个 &std::process::Command,用于需要标准库类型的地方。
Sourcepub fn as_std_mut(&mut self) -> &mut StdCommand
pub fn as_std_mut(&mut self) -> &mut StdCommand
廉价地转换为一个 &mut std::process::Command,用于需要标准库类型的地方。
Sourcepub fn into_std(self) -> StdCommand
pub fn into_std(self) -> StdCommand
廉价地转换为一个 std::process::Command。
注意,Tokio 特有的选项将会丢失。目前这仅适用于 kill_on_drop。
Sourcepub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Command
pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Command
添加一个传递给程序的参数。
每次只能传递一个参数。因此,若要一次传递多个参数,可以这样做:
let mut command = tokio::process::Command::new("sh");
command.arg("-C /path/to/repo");
用法示例:
let mut command = tokio::process::Command::new("sh");
command.arg("-C");
command.arg("/path/to/repo");
要传递多个参数,请参阅 args。
§示例
基本用法:
use tokio::process::Command;
let output = Command::new("ls")
.arg("-l")
.arg("-a")
.output().await.unwrap();
Sourcepub fn raw_arg<S: AsRef<OsStr>>(
&mut self,
text_to_append_as_is: S,
) -> &mut Command
pub fn raw_arg<S: AsRef<OsStr>>( &mut self, text_to_append_as_is: S, ) -> &mut Command
在命令行末尾追加未经任何引号包裹或转义的字面文本。
这在向 cmd.exe /c 传递参数时很有用,
因为它不遵循 CommandLineToArgvW 的转义规则。
Sourcepub fn env<K, V>(&mut self, key: K, val: V) -> &mut Command
pub fn env<K, V>(&mut self, key: K, val: V) -> &mut Command
插入或更新一个环境变量映射。
注意,环境变量名在 Windows 上大小写不敏感(但保留原始大小写), 而在所有其它平台上大小写敏感。
§示例
基本用法:
use tokio::process::Command;
let output = Command::new("ls")
.env("PATH", "/bin")
.output().await.unwrap();Sourcepub fn envs<I, K, V>(&mut self, vars: I) -> &mut Command
pub fn envs<I, K, V>(&mut self, vars: I) -> &mut Command
添加或更新多个环境变量映射。
§示例
基本用法:
use tokio::process::Command;
use std::process::{Stdio};
use std::env;
use std::collections::HashMap;
let filtered_env : HashMap<String, String> =
env::vars().filter(|&(ref k, _)|
k == "TERM" || k == "TZ" || k == "LANG" || k == "PATH"
).collect();
let output = Command::new("printenv")
.stdin(Stdio::null())
.stdout(Stdio::inherit())
.env_clear()
.envs(&filtered_env)
.output().await.unwrap();Sourcepub fn env_remove<K: AsRef<OsStr>>(&mut self, key: K) -> &mut Command
pub fn env_remove<K: AsRef<OsStr>>(&mut self, key: K) -> &mut Command
移除一个环境变量映射。
§示例
基本用法:
use tokio::process::Command;
let output = Command::new("ls")
.env_remove("PATH")
.output().await.unwrap();Sourcepub fn env_clear(&mut self) -> &mut Command
pub fn env_clear(&mut self) -> &mut Command
清除子进程的全部环境变量映射。
§示例
基本用法:
use tokio::process::Command;
let output = Command::new("ls")
.env_clear()
.output().await.unwrap();Sourcepub fn current_dir<P: AsRef<Path>>(&mut self, dir: P) -> &mut Command
pub fn current_dir<P: AsRef<Path>>(&mut self, dir: P) -> &mut Command
设置子进程的工作目录。
§Platform-specific behavior
如果程序路径是相对的(例如 "./script.sh"),
那么它究竟是相对于父进程的工作目录还是相对于 current_dir 来解释并不明确。
这种情况下的行为因平台而异且不稳定,
建议改用 canonicalize 来获取程序的绝对路径。
§示例
基本用法:
use tokio::process::Command;
let output = Command::new("ls")
.current_dir("/bin")
.output().await.unwrap();Sourcepub fn kill_on_drop(&mut self, kill_on_drop: bool) -> &mut Command
pub fn kill_on_drop(&mut self, kill_on_drop: bool) -> &mut Command
控制在对应的 Child 句柄被 drop 时,是否应对已派生的子进程调用 kill 操作。
默认情况下,该值被视为 false,
即下一个派生出的进程在被 drop 时不会被终止 —— 这与标准库的行为一致。
§Caveats
在 Unix 平台上,进程退出后必须由其父进程“回收”,以释放所有操作系统资源。 已退出但尚未被父进程回收的子进程被视为“僵尸”进程。 此类进程会持续占用系统限制,僵尸进程过多会导致无法再派生新的进程。
尽管向子进程发送 kill 信号是一个同步操作,
但产生的僵尸进程不能在析构函数中通过 .await 等待回收,
以免阻塞其它任务。tokio 运行时将尽力在后台尝试回收并清理这些进程,
但不就此过程的执行频率或速度提供任何额外保证。
如果需要更强的保证,建议尽可能避免 drop Child 句柄,
而是尽量使用 child.wait().await 或 child.kill().await。
Sourcepub fn creation_flags(&mut self, flags: u32) -> &mut Command
pub fn creation_flags(&mut self, flags: u32) -> &mut Command
设置传递给 CreateProcess 的进程创建标志。
它们始终会与 CREATE_UNICODE_ENVIRONMENT 进行 OR 运算。
Sourcepub fn spawn(&mut self) -> Result<Child>
pub fn spawn(&mut self) -> Result<Child>
将命令作为子进程执行,并返回它的句柄。
默认情况下,stdin、stdout 和 stderr 继承自父进程。
此方法会同步派生子进程,并返回一个 future-aware 子进程的句柄。
返回的 Child 本身实现了 Future,
用于获取子进程的 ExitStatus;
此外 Child 还提供了获取 stdin、stdout 和 stderr 流句柄的方法。
该子进程的所有 I/O 都将关联到当前默认的事件循环。
§示例
基本用法:
use tokio::process::Command;
async fn run_ls() -> std::process::ExitStatus {
Command::new("ls")
.spawn()
.expect("ls command failed to start")
.wait()
.await
.expect("ls command failed to run")
}§Caveats
§Dropping/Cancellation
与标准库的行为类似,与 future 范式的“drop 即取消”不同,默认情况下,
派生出的进程即使在 Child 句柄被 drop 后仍会继续执行。
Command::kill_on_drop 方法可用于修改此行为,
当 Child 包装器在子进程退出前被 drop 时终止子进程。
§Unix Processes
在 Unix 平台上,进程退出后必须由其父进程“回收”,以释放所有操作系统资源。 已退出但尚未被父进程回收的子进程被视为“僵尸”进程。 此类进程会持续占用系统限制,僵尸进程过多会导致无法再派生新的进程。
tokio 运行时将尽力尝试回收并清理它派生的任何进程。 但不就此过程的执行频率或速度提供任何额外保证。
如果需要更严格的清理保证,建议在完全 await 完毕之前,避免 drop
Child 进程句柄。
§Errors
在 Unix 平台上,如果达到系统进程上限(包括系统上正在运行的其它应用程序),
此方法将以 std::io::ErrorKind::WouldBlock 失败。
Sourcepub fn status(&mut self) -> impl Future<Output = Result<ExitStatus>>
pub fn status(&mut self) -> impl Future<Output = Result<ExitStatus>>
将命令作为子进程执行,等待其完成并收集其退出状态。
默认情况下,stdin、stdout 和 stderr 继承自父进程。 如果任意输入/输出句柄被设置为管道,则它们会在子进程派生后立即关闭。
该子进程的所有 I/O 都将关联到当前默认的事件循环。
如果 kill_on_drop 被设置为 true,
则此函数返回的 future 的析构函数将终止子进程。
§Errors
如果无法派生子进程,或在等待其状态时发生错误, 此 future 将返回错误。
在 Unix 平台上,如果达到系统进程上限(包括系统上正在运行的其它应用程序),
此方法将以 std::io::ErrorKind::WouldBlock 失败。
§示例
基本用法:
use tokio::process::Command;
async fn run_ls() -> std::process::ExitStatus {
Command::new("ls")
.status()
.await
.expect("ls command failed to run")
}Sourcepub fn output(&mut self) -> impl Future<Output = Result<Output>>
pub fn output(&mut self) -> impl Future<Output = Result<Output>>
将命令作为子进程执行,等待其完成并收集其全部输出。
注意:与标准库不同, 此方法会无条件地将 stdout/stderr 句柄配置为管道, 即使它们之前已被配置。 如果不需要此行为,应使用
spawn方法, 并在子进程上结合使用wait_with_output方法。
此方法将返回一个 future,表示对子进程 stdout/stderr 的收集。
它将解析为标准库中的 Output 类型,
其中包含 stdout 和 stderr(作为 Vec<u8>),
以及表示进程退出方式的 ExitStatus。
该子进程的所有 I/O 都将关联到当前默认的事件循环。
如果 kill_on_drop 被设置为 true,
则此函数返回的 future 的析构函数将终止子进程。
§Errors
如果无法派生子进程,或在等待其状态时发生错误, 此 future 将返回错误。
在 Unix 平台上,如果达到系统进程上限(包括系统上正在运行的其它应用程序),
此方法将以 std::io::ErrorKind::WouldBlock 失败。
§示例
基本用法:
use tokio::process::Command;
async fn run_ls() {
let output: std::process::Output = Command::new("ls")
.output()
.await
.expect("ls command failed to run");
println!("stderr of ls: {:?}", output.stderr);
}Sourcepub fn get_kill_on_drop(&self) -> bool
pub fn get_kill_on_drop(&self) -> bool
返回先前由 Command::kill_on_drop 设置的布尔值。
注意,如果您之前没有调用过 Command::kill_on_drop,
此处将返回默认值 false。
§示例
use tokio::process::Command;
let mut cmd = Command::new("echo");
assert!(!cmd.get_kill_on_drop());
cmd.kill_on_drop(true);
assert!(cmd.get_kill_on_drop());