私はシェルコマンドを実行して、その出力を圧縮しようとしています。 問題は、Readerを必要とするAPIとのインターフェースが必要なことです。 Iは、以下の(簡略化コード)としようとしたことについてgzipからReaderへのパイプコマンド出力
:
package main
import (
"encoding/hex"
"testing"
"fmt"
"io"
"io/ioutil"
"os/exec"
"compress/gzip"
)
func TestPipe(t *testing.T) {
cmd := exec.Command("echo", "hello_from_echo")
reader, writer := io.Pipe()
gzW := gzip.NewWriter(writer)
cmd.Stdout = gzW
cmd.Start()
go func() {
fmt.Println("Waiting")
cmd.Wait()
fmt.Println("wait done")
// writer.Close()
// gzW.Close()
}()
msg, _ := ioutil.ReadAll(reader)
fmt.Println(hex.EncodeToString(msg))
}
問題はREADALLは永遠ハングすることです。もし私がgzW
を閉じても何も変わりません。しかし、私はwriter
変数を閉じると、今のプログラムはハングせずに終了しますが、出力は次のようになります。
$ go test -run Pipe
Waiting
wait done
1f8b080000096e8800ff
PASS
しかし、関係なく、私はエコー何の出力が同じではありません。私がこのようなコマンドラインから試してみると、echo "hello_from_echo" | gzip | hexdump
の出力はまったく違うので、そのアプローチには何か問題があります。
何か問題が発生する可能性がありますか?
おかげで、事前
出力を閉じないでください。 (これはgzWです) 今のところ、手動でgzWでflushを呼び出すことで解決しましたが、解決策を試してみて –
@FerminSilva、いいえ、Closeを呼び出さないでください。 (Cmd.Stdoutは 'io.Writer'であり、' io.WriteCloser'ではありません)。また、 'gzip.Writer'を閉じなければ、crcフッターは書き込まれず、出力の解凍はエラーになります。 – JimB
知っておいてよかった!ところで、私のコードが既にgorutineに入っている場合、クローズコールのブロックに関する問題は何ですか? –