繁体   English   中英

使用'bash -c'时std :: process:Command不返回Err()结果

[英]std::process:Command not returning Err() result when using 'bash -c'

我试图理解为什么在使用bash -c表达式运行命令时为什么没有得到Err()结果。

这是一个示例,下面是输出。 我期望out2out3Err()但是out3是具有失败状态的Ok()

我正在使用bash -c从给定的字符串执行命令,这很容易。

可以使用bash -c语法获得Err()结果吗?

#![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);
}

输出:

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" })

我从命令行尝试过

$ bash -c wrongcommand

$ wrongcommand

两者都返回相同的退出代码(127)。 这就是为什么我期望Command以相同的方式失败的原因。

这很容易解释。 遵循错误代码列表

out1Ok原因很明显

out2是一种Err类型,因为Command直接查找该进程,找不到该进程,并返回ENOENT (代码2)。 此错误发生锈中,实际上未执行任何操作。

out3Ok ,因为过程Commandbash ,并返回其状态。 在这种情况下,它找不到命令,因此按bash状态返回127。但是,这并不容易,因为ExitStatus包含一层附加信息。 在unix上,当进程失败时,它实际上返回一个16位/ 32位整数(基于platform / libc / etc),分为两个:

  • 最高位是触发返回的信号
  • 最低的8位是进程的返回状态

而且,毫不奇怪,如果我们将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"))
});

您可以在操场上玩。 success()是子进程成功的可靠指标; 它所做的只是检查退出状态的最低有效8位是否为非零。

显然,如果进程成功返回非零值,则无济于事,但这是另一个问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM