Rustのstd::process::Commandで引っかかったところ
2019/12/26 18:30 | 公開 |
git-authorというgitのサブコマンドを作っているときにstd::process::Command
を使用したのですが、output()
の返り値ので引っかかったことがあったのでメモがてら書いていきます。
output()
がOk
を返してもコマンドの実行に成功したとは限らない
例えばgit config --local user.name
と同じことをしようと思うと
// outputはio::Result<Output>型
let result = std::process::Command::new("git")
.arg("config")
.arg("--local")
.arg("user.name")
.output();
となります。
output()
はResult
型を返すのでコマンド実行に失敗すればErr
が返ってくるのだろうと考えていましが、実行に失敗してもOk
が返ってくるパターンがありました。
例えば
// `git hoge`を実行
let result = std::process::Command::new("git").arg("hoge").output();
let output = result.unwrap();
のように存在しないサブコマンドhoge
を実行しようとするとコマンドの実行結果は失敗なのにも関わらずoutput()
はOk
を返します。
ただしoutput.stdout
は空のままでoutput.stderr
に文字列が入っています。
また、先程の
// `git config --local user.name`を実行
std::process::Command::new("git")
.arg("config")
.arg("--local")
.arg("user.name")
.output();
も、ローカルのuser.name
が設定されていない時は失敗として扱われますが、output()
はOk
を返します。
Err
を返すとき
ではどのようなときにErr
を返すかというと
// `fuga`を実行
let output = std::process::Command::new("fuga").output();
のように存在しないコマンドを実行しようとしたときにErr
を返しました。
結論
実行に成功したかどうかを確認したい時はoutput()
の返り値がOk
かどうかに加えてstatus.success()
がtrueかどうかを確認しましょう。
let result = std::process::Command::new("command").output();
if let Ok(output) = result {
if output.status.success() {
// 成功
}
else {
// 失敗
}
}
else {
// 失敗
}