Jua*_*ias 4 bash command-line rust
我试图了解为什么Err()使用bash -c表达式运行命令时没有得到结果。
这是一个示例,下面是输出。我希望out2和out3是一个Err(),但是out3是一种Ok()与失败的状态。
我bash -c用来从给定的字符串执行命令,这很容易。
可以Err()使用bash -c语法获得结果吗?
#![allow(unused)]
use std::process::{Command, Output};
fn main() {
let out1 = Command::new("bash").arg("-c").arg("ls").output();
println!("out1: {:?}", out1);
let out2 = Command::new("wrongcommand").arg("-c").arg("ls").output();
println!("out2: {:?}", out2);
let out3 = Command::new("bash").arg("-c").arg("wrongcommand").output();
println!("out3: {:?}", out3);
}
Run Code Online (Sandbox Code Playgroud)
输出:
out1: Ok(Output { status: ExitStatus(ExitStatus(0)), stdout: "Cargo.lock\nCargo.toml\ncrate-information.json\nsrc\ntarget\n", stderr: "" })
out2: Err(Os { code: 2, kind: NotFound, message: "No such file or directory" })
out3: Ok(Output { status: ExitStatus(ExitStatus(32512)), stdout: "", stderr: "bash: wrongcommand: command not found\n" })
Run Code Online (Sandbox Code Playgroud)
我从命令行尝试过
$ bash -c wrongcommand
Run Code Online (Sandbox Code Playgroud)
和
$ wrongcommand
Run Code Online (Sandbox Code Playgroud)
两者都返回相同的退出代码(127)。这就是为什么我期望Command以相同的方式失败的原因。
这很容易解释。遵循错误代码列表
out1是Ok出于明显的原因
out2是一种Err类型,因为Command直接查找该过程,找不到它,然后返回了ENOENT(代码2)。此错误发生在锈中,实际上未执行任何操作。
out3是Ok因为运行的进程Command是bash,并且它返回了其状态。在这种情况下,它不会找到命令,因此按bash状态返回127。但是,这并不容易,因为中包含了附加的信息层ExitStatus。在unix上,当进程失败时,它实际上返回一个16位/ 32位整数(基于platform / libc / etc),分为两个:
而且,毫不奇怪,如果我们将32512 8位右移(这是一个u16),我们将得到127!
要点很简单:
Err 绝对意味着该流程未运行Ok表示主流程已运行,但您需要检查ExitStatus::success()以确认其确实已完成(即退出状态为0)您可以这样恢复它:
Command::new("bash").arg("-c").arg("wrongcommand").output().and_then(|r| match r.status.success() {
true => Ok(r),
false => Err(io::Error::new(io::ErrorKind::InvalidData, "Process error"))
});
Run Code Online (Sandbox Code Playgroud)
您可以在操场上玩。success()是子进程成功的可靠指标;它所做的只是检查退出状态的最低有效8位是否为非零。
显然,如果进程成功返回非零值,则无济于事,但这是另一个问题。