[英]std::process:Command not returning Err() result when using 'bash -c'
I'm trying to understand why I'm not getting an Err()
result when using bash -c
expression to run a command. 我试图理解为什么在使用bash -c
表达式运行命令时为什么没有得到Err()
结果。
Here is an example and the output below. 这是一个示例,下面是输出。 I expect out2
and out3
to be an Err()
but out3
is an Ok()
with the failed status. 我期望out2
和out3
是Err()
但是out3
是具有失败状态的Ok()
。
I'm using bash -c
to execute a command from a given string, which is easy. 我正在使用bash -c
从给定的字符串执行命令,这很容易。
It's possible to get an Err()
result using bash -c
syntax? 可以使用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);
}
Output: 输出:
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" })
I tried from command line and 我从命令行尝试过
$ bash -c wrongcommand
and 和
$ wrongcommand
and both return the same exit code (127). 两者都返回相同的退出代码(127)。 That's why I expected that Command failed in the same way. 这就是为什么我期望Command以相同的方式失败的原因。
That can be explained pretty easily. 这很容易解释。 Follow along on the list of error codes 遵循错误代码列表
out1
is Ok
for obvious reasons out1
是Ok
原因很明显
out2
is an Err
type because Command
directly looked for the process, could not find it, and returned ENOENT
(code 2). out2
是一种Err
类型,因为Command
直接查找该进程,找不到该进程,并返回ENOENT
(代码2)。 This error happened within rust, nothing was actually executed. 此错误发生在锈中,实际上未执行任何操作。
out3
is Ok
because the process that Command
ran is bash
, and it returned its status. out3
是Ok
,因为过程Command
冉bash
,并返回其状态。 In this case, it wouldn't have found the command, so by bash statuses, it'll have returned 127. However, it's not that easy, because there is an additional layer of information contained in ExitStatus
. 在这种情况下,它找不到命令,因此按bash状态返回127。但是,这并不容易,因为ExitStatus
包含一层附加信息。 On unix, when a process fails, it actually returns a 16bit/32bit integer (based on platform/libc/etc), separated in two: 在unix上,当进程失败时,它实际上返回一个16位/ 32位整数(基于platform / libc / etc),分为两个:
And, to no surprise, if we shift 32512 8 bits to the right (it was an u16
), we get... 127! 而且,毫不奇怪,如果我们将32512 8位右移(这是一个u16
),我们得到... 127!
The takeaway is simple: 要点很简单:
Err
definitely means the process didn't run Err
肯定表示该流程未运行 Ok
means the main process ran, but you'll need to check ExitStatus::success()
to confirm that it actually did (ie 0 as exit status) Ok
意味着主进程已经运行,但是您需要检查ExitStatus::success()
以确认它确实已经完成(例如,退出状态为0) You could recover it like so: 您可以这样恢复它:
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"))
});
You can play with this on the playground . 您可以在操场上玩。 success()
is a decently reliable indicator of child process success; success()
是子进程成功的可靠指标; all it does is check if the least significant 8 bits of the exit status is non-zero. 它所做的只是检查退出状态的最低有效8位是否为非零。
Obviously, this does not help if a process returns non-zero on success, but that's a different problem. 显然,如果进程成功返回非零值,则无济于事,但这是另一个问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.