Go

Golangで標準入力がパイプで渡されたものか判定する

More than 3 years have passed since last update.

一般的な手法のfmt.Scanbufioscannerの場合、パイプで標準入力が渡されなかった時は入力待ちになる。

package main

import (
"fmt"
)

func main() {
var stdin string
fmt.Scan(&stdin)
fmt.Println("渡された標準入力を出力:", stdin)
}

実行結果(パイプなし)

$ go run scan.go

ここで入力待ち
渡された標準入力を出力: ここで入力待ち

実行結果(パイプあり)

$ echo "パイプの場合は待たずにすぐ出力" | go run scan.go

渡された標準入力を出力: パイプの場合は待たずにすぐ出力


パイプで渡された時だけ処理する

入力待ちにしたくない。パイプで渡された時だけ標準入力を取れれば良い、という時はterminal.IsTerminalを使う。

パイプが無い場合はFD値が0(stdin)、パイプがある場合はFD値が0以外で判定。

https://godoc.org/golang.org/x/crypto/ssh/terminal#IsTerminal

package main

import (
"fmt"
"golang.org/x/crypto/ssh/terminal"
"io/ioutil"
"os"
)

func main() {
fmt.Println(terminal.IsTerminal(0))
if terminal.IsTerminal(0) {
fmt.Println("パイプ無し(FD値0)")
} else {
b, _ := ioutil.ReadAll(os.Stdin)
fmt.Println("パイプで渡された内容(FD値0以外):", string(b))
}
}

実行結果(パイプなし)

$ go run stdin.go

true
パイプ無し(FD値0)

実行結果(パイプあり)

$ echo -n "パイプで渡す" | go run stdin.go

false
パイプで渡された内容(FD値0以外): パイプで渡す