長時間実行されるコマンドが実行され、その出力を親プロセスとログ ファイルの両方に継続的にストリーミングする必要があるシナリオ、 cmd.StdoutPipe() メソッドを利用して出力をキャプチャできます。
cmd := exec.Command("sh", "-c", "some long runnig task") stdout, _ := cmd.StdoutPipe() cmd.Start() scanner := bufio.NewScanner(stdout) for scanner.Scan() { m := scanner.Text() fmt.Println(m) log.Printf(m) } cmd.Wait()
ただし、このアプローチでは、部分的な結果をストリーミングするのではなく、単一の文字列として最終出力します。
bufio.NewScanner() 関数は行に対して動作し、改行文字が出現すると完全な行を返します。実行中のコマンドで改行文字が生成されない場合、出力はすぐにはストリーミングされません。
この制限に対処するには、考慮すべきアプローチがいくつかあります。
単語または文字で読む:
分割を設定するScanner.Split() を使用する関数を使用すると、単語または文字で入力をスキャンし、生成された出力をキャプチャできます。
scanner := bufio.NewScanner(stdout) scanner.Split(bufio.ScanRunes)
マニュアル読み取り:
バイトごとまたはルーンごとに読み取ることで、改行に依存せずに生成された出力をキャプチャできます
oneByte := make([]byte, 1) for { _, err := stdout.Read(oneByte) if err != nil { break } fmt.Printf("%c", oneByte[0]) } oneRune := make([]byte, utf8.UTFMax) for { count, err := stdout.Read(oneRune) if err != nil { break } fmt.Printf("%s", oneRune[:count]) }
子プロセスの標準出力およびエラー ストリームのバッファ サイズを管理することが重要です。デフォルトでは、これらのバッファーが読み取られない場合、子プロセスがハングする可能性があります。したがって、常に stdout ストリームと stderr ストリームの両方を読み取ることをお勧めします。
以上がGo で長時間実行されるコマンドから部分的な出力をストリーミングする方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。