以下のコードを実行すると:
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
ただし、これはエラーの正確な原因をデバッグするのに役立ちません。
より詳細な情報を取得する方法は?
解決策は、CommandオブジェクトのStderr
プロパティを使用することです。これは次のように実行できます。
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:検索:-exec:終了「;」なしまたは「+」
編集:
上記のコードでは、エラーが発生した場合、メッセージはstderrに出力され、コマンドはゼロ以外のエラーコードを返します。これは多かれ少なかれ標準です。
ただし、@ snorberhuisが後述するように、一部のコマンドはエラーをstdoutに出力します。他のコマンドはstderrに出力されますが、エラーコード0を返します(この場合、err
はnil
になります)。また、stderrにメッセージがあるということは、必ずしもエラーがあることを意味するわけではありません(ffmpegツールはこれを頻繁に行います)。
したがって、基本的には、期待するコマンドに対応するために上記のコードを微調整する必要があるかもしれません。
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