1. ホーム
  2. go

[解決済み] Goで複数のコマンドをパイプでつなぐには?

2023-06-02 17:51:23

質問

Go で複数の外部コマンドをパイプでつなぐにはどうしたらよいでしょうか。このコードを試しましたが、次のようなエラーが発生しました。 exit status 1 .

package main

import (
    "io"
    "log"
    "os"
    "os/exec"
)

func main() {
    c1 := exec.Command("ls")
    stdout1, err := c1.StdoutPipe()
    if err != nil {
        log.Fatal(err)
    }

    if err = c1.Start(); err != nil {
        log.Fatal(err)
    }
    if err = c1.Wait(); err != nil {
        log.Fatal(err)
    }

    c2 := exec.Command("wc", "-l")
    c2.Stdin = stdout1

    stdout2, err := c2.StdoutPipe()
    if err != nil {
        log.Fatal(err)
    }

    if err = c2.Start(); err != nil {
        log.Fatal(err)
    }
    if err = c2.Wait(); err != nil {
        log.Fatal(err)
    }

    io.Copy(os.Stdout, stdout2)
}

どのように解決するのですか?

<ブロッククオート

StdoutPipeは、コマンドの起動時にコマンドの標準出力に接続されるパイプを返します。 に接続されるパイプを返します。このパイプは Waitがコマンドの終了を確認した後、自動的に閉じられます。

(以下 http://golang.org/pkg/os/exec/#Cmd.StdinPipe )

を行うということは c1.Wait を閉じる。 stdoutPipe .

動作する例を作ってみました(単なるデモです、エラーキャッチを追加してください!) :

package main

import (
    "bytes"
    "io"
    "os"
    "os/exec"
)

func main() {
    c1 := exec.Command("ls")
    c2 := exec.Command("wc", "-l")

    r, w := io.Pipe() 
    c1.Stdout = w
    c2.Stdin = r

    var b2 bytes.Buffer
    c2.Stdout = &b2

    c1.Start()
    c2.Start()
    c1.Wait()
    w.Close()
    c2.Wait()
    io.Copy(os.Stdout, &b2)
}