いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-139 (exec.Command で標準出力と標準エラー出力を両方取得)

概要

よく忘れるのでメモメモ。

少し前に exec.Command について以下をメモしていました。

devlights.hatenablog.com

上の記事のサンプルでは (*Cmd).Output() を使って標準出力を取得していましたが、標準エラー出力も含めて欲しいときがあります。

そんなときは、(*Cmd).CombinedOutput() を利用すると標準出力と標準エラー出力を両方取得してくれます。便利ですねー。

サンプル

package cmdexec

import (
    "errors"
    "os/exec"
    "runtime"

    "github.com/devlights/gomy/output"
)

// OneShotWithStderr は、コマンドを一発実行して結果を取得するサンプルです。(標準エラー出力も含む)
//
// REFERENCES:
//   - https://golang.org/pkg/os/exec/#example_Cmd_CombinedOutput
//   - https://www.gnu.org/software/bash/manual/bash.html#Redirecting-Standard-Output-and-Standard-Error
//   - https://tldp.org/LDP/abs/html/io-redirection.html
func OneShotWithStderr() error {
    if runtime.GOOS == "windows" {
        return errors.New("this example cannot run on Windows, sorry")
    }

    const (
        Shell = "/bin/bash"
    )

    var (
        cmd *exec.Cmd // コマンド
        out []byte    // 実行結果
        err error     // 実行時エラー
    )

    //
    // (*Cmd).CombinedOutput() を使うと標準出力と標準エラー出力を結合した結果を取得できる
    // 以下では hello を標準出力に world を標準エラー出力に出力している
    //
    cmd = exec.Command(Shell, "-c", "echo hello; echo world 1>&2")
    out, err = cmd.CombinedOutput()
    if err != nil {
        return err
    }

    output.Stdoutf("[CombinedOutput]", "\n%s", string(out))
    output.StdoutHr()

    //
    // Output だと、標準出力のみを対象とするので world は出力されない
    //
    cmd = exec.Command(Shell, "-c", "echo hello; echo world 1>&2")
    out, err = cmd.Output()
    if err != nil {
        return err
    }

    output.Stdoutf("[Output]", "\n%s", string(out))
    output.StdoutHr()

    return nil
}

try-golang/oneshotwithstderr.go at master · devlights/try-golang · GitHub

実行すると以下のようになります。

gitpod /workspace/try-golang $ make run

go get -d ./...
go run -race github.com/devlights/try-golang/cmd/trygolang -onetime -example ""

ENTER EXAMPLE NAME: cmdexec_oneshot_with_stderr
[Name] "cmdexec_oneshot_with_stderr"

[CombinedOutput]     
hello
world
-------------------------------------------------- 
[Output]             
hello
-------------------------------------------------- 


[Elapsed] 4.456165ms

CombinedOutputを使っている場合はちゃんと標準エラー出力も含めてくれていますね。

参考資料

golang.org

www.gnu.org

tldp.org


過去の記事については、以下のページからご参照下さい。

  • いろいろ備忘録日記まとめ

devlights.github.io

サンプルコードは、以下の場所で公開しています。

  • いろいろ備忘録日記サンプルソース置き場

github.com

github.com

github.com