60

以下のコードを実行すると:

cmd := exec.Command("find", "/", "-maxdepth", "1", "-exec", "wc", "-c", "{}", "\\")
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
if err != nil {
    fmt.Println(err)
    return
}
fmt.Println("Result: " + out.String())

このエラーが発生しています:

終了ステータス 1

ただし、これはエラーの正確な原因をデバッグするのには役立ちません。

より詳細な情報を取得するにはどうすればよいですか?

4

2 に答える 2

130

Stderr解決策は、Command オブジェクトのプロパティを使用することです。これは次のように行うことができます。

cmd := exec.Command("find", "/", "-maxdepth", "1", "-exec", "wc", "-c", "{}", "\\")
var out bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &stderr
err := cmd.Run()
if err != nil {
    fmt.Println(fmt.Sprint(err) + ": " + stderr.String())
    return
}
fmt.Println("Result: " + out.String())

上記のコードを実行すると、問題が何であるかが明確になります。

終了ステータス 1: find: -exec: 終端なし ";" または「+」

編集:

上記のコードでは、エラーが発生した場合、メッセージが stderr に出力され、コマンドがゼロ以外のエラー コードを返すことが期待されます。これは多かれ少なかれ標準です。

ただし、@snorberhuis が後述するように、一部のコマンドはエラーを stdout に出力します。他のコマンドは stderr に出力される可能性がありますが、エラー コード 0 を返します (この場合errは になりますnil)。また、stderr にメッセージがあるからといって、必ずしもエラーがあるとは限りません (ffmpeg ツールはこれを頻繁に行います)。

したがって、基本的には、期待するコマンドに対応するために上記のコードを微調整する必要がある場合があります。

于 2013-08-10T07:32:18.960 に答える
44

Laurent が述べたように、Stderr ファイル記述子をオーバーライドして stderr 出力をキャプチャし、エラー メッセージを改善することができます。個人的には、CombinedOutput比較的単純なことを行う場合は、コマンドにメソッドを使用することを好みます。

cmd := exec.Command("find", "/", "-maxdepth", "1", "-exec", "wc", "-c", "{}", "\\")
output, err := cmd.CombinedOutput()
if err != nil {
    fmt.Println(fmt.Sprint(err) + ": " + string(output))
    return
}
fmt.Println(string(output))

上記の例の play.golang.org リンクは次のとおりです: http://play.golang.org/p/z8k9zO755P

于 2013-08-11T22:01:22.720 に答える