Skip to content

Commit c64ba83

Browse files
committed
Update examples
1 parent 1964c2f commit c64ba83

File tree

2 files changed

+69
-6
lines changed

2 files changed

+69
-6
lines changed

examples/basic/cmdexec/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@
1313
| withenv.go | cmdexec_env | *exec.Cmd 実行時に追加の環境変数を指定するサンプルです |
1414
| withdir.go | cmdexec_dir | *exec.Cmd 実行時にワーキングディレクトリを指定するサンプルです |
1515
| withslice.go | cmdexec_slice | *exec.Cmd 実行時にスライスの値をコマンドの引数で指定するサンプルです |
16+
| ospipe.go | cmdexec_ospipe | (*Cmd).Stdout に os.Pipe の io.Writer を接続して処理するサンプルです |

examples/basic/cmdexec/ospipe.go

Lines changed: 68 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ package cmdexec
22

33
import (
44
"bufio"
5-
"log"
5+
"fmt"
6+
"io"
67
"os"
78
"os/exec"
89
)
@@ -12,17 +13,46 @@ import (
1213
// # REFERENCES
1314
// - https://pkg.go.dev/os@go1.24.4#Pipe
1415
func OsPipe() error {
16+
//
17+
// (*Cmd).StdoutPipe()で同じことが出来るが
18+
// os.Pipe()の使い方を勉強するために
19+
// 意図的に利用している
20+
//
21+
22+
///////////////////////////////////
23+
// パイプ取得
24+
///////////////////////////////////
25+
1526
var (
1627
pr *os.File
1728
pw *os.File
1829
err error
1930
)
20-
pr, pw, err = os.Pipe()
21-
if err != nil {
31+
if pr, pw, err = os.Pipe(); err != nil {
2232
return err
2333
}
2434
defer pr.Close()
2535

36+
///////////////////////////////////
37+
// コマンド実行
38+
//
39+
// git log コマンドを実行しているため
40+
// リポジトリによっては長大な出力が発生する。
41+
//
42+
// 簡易なコマンド実行である (*Cmd).Output() で取得しようとすると
43+
// OSのバッファが一杯になってしまう可能性があるため、このような場合は
44+
// ストリーミング処理が必須となる。
45+
//
46+
// 以下で実行している git コマンドのオプションは以下の通り
47+
// - --no-pager : ページャーを使用しない
48+
// - log : ログを表示
49+
// - -m : マージコミットの差分も表示
50+
// - -r : 再帰的に処理
51+
// - --name-only : ファイル名のみ表示
52+
// - --pretty=raw: 生フォーマットで表示
53+
// - -z : NULL文字で区切る
54+
///////////////////////////////////
55+
2656
var (
2757
name = "git"
2858
args = []string{"--no-pager", "log", "-m", "-r", "--name-only", "--pretty=raw", "-z"}
@@ -34,7 +64,10 @@ func OsPipe() error {
3464
return err
3565
}
3666

37-
// 終了待機
67+
///////////////////////////////////
68+
// 終了待機用のゴルーチンを用意
69+
///////////////////////////////////
70+
3871
var (
3972
done = make(chan error, 1)
4073
)
@@ -43,26 +76,55 @@ func OsPipe() error {
4376
done <- cmd.Wait()
4477
}()
4578

79+
///////////////////////////////////
80+
// コマンドの出力を読み出し
81+
///////////////////////////////////
82+
4683
const (
47-
MaxTokenSize = 1024 * 1024
84+
MaxTokenSize = 1024 * 1024 // 1行のサイズが大きい可能性を考慮してバッファサイズを底上げ
4885
)
4986
var (
5087
scanner = bufio.NewScanner(pr)
5188
buf = make([]byte, MaxTokenSize)
89+
count int
5290
)
5391
scanner.Buffer(buf, MaxTokenSize)
5492

5593
for scanner.Scan() {
56-
log.Println(scanner.Text())
94+
io.Discard.Write(scanner.Bytes())
95+
count++
5796
}
5897

5998
if err = scanner.Err(); err != nil {
6099
return err
61100
}
62101

102+
///////////////////////////////////
103+
// コマンド終了待機
104+
///////////////////////////////////
105+
63106
if err = <-done; err != nil {
64107
return err
65108
}
66109

110+
///////////////////////////////////
111+
// 結果出力
112+
///////////////////////////////////
113+
114+
fmt.Printf("Total lines: %d\n", count)
115+
67116
return nil
117+
118+
/*
119+
$ task
120+
task: [build] go build .
121+
task: [run] ./try-golang -onetime
122+
123+
ENTER EXAMPLE NAME: cmdexec_ospipe
124+
125+
[Name] "cmdexec_ospipe"
126+
Total lines: 29988
127+
128+
[Elapsed] 123.966649ms
129+
*/
68130
}

0 commit comments

Comments
 (0)