標準入力からデータを受け取るようなプログラムを起動させようとして、stdin に WriteString したらハマりになったので対処法をメモしておきます。
ProtocolBuffer のプラグイン書いてて踏みましたが、Go の周辺ツールとかカスタムしようとすると同じ感じで踏むかもしれません。
Windows で 4KB 以上のデータを書き込んだ場合にのみ発生し、4KB 以下の場合や Windows 以外の OS の場合は発生しません。
例えばこんなコード。
func main() {
content, _ := ioutil.ReadFile("test.txt") // 適当に 4KB 以上のテキスト
c := exec.Command("more")
stdin, _ := c.StdinPipe()
io.WriteString(stdin, string(content)) // ここで返ってこない
stdin.Close()
}
恐らく、パイプのバッファが足りなくなって、空くのを待っているけれども、
書き込みが終わってないのでプログラムが起動せず、空ける人がいないという状況と思われる。
以下のようにしたら、とりあえず動いた。
func main() {
content, _ := ioutil.ReadFile("test.txt") // 適当に 4KB 以上のテキスト
c := exec.Command("more")
stdin, _ := c.StdinPipe()
go func() {
defer stdin.Close()
io.WriteString(stdin, string(content))
}()
output, _ := c.CombinedOutput()
fmt.Print(string(output))
}