Help us understand the problem. What is going on with this article?

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以外): パイプで渡す
tanksuzuki
インフラ屋だったりバックエンド屋だったりフロント屋だったり、色々です。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away