1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Go 2Advent Calendar 2020

Day 7

Goで標準入力がターミナルかどうかを判定する(Goで標準入力がファイルかどうかを判定する)

Posted at

概要

Vim を起動する際に以下のように標準入力をファイルにすると警告が出ます。

$ vim < test.txt
Vim: Warning: Input is not from a terminal
...
...

テキストエディタやコマンドラインツールを作っていると標準入力がファイルかターミナルか知りたい場合があります。
今回はGoにおいてそれをどうやって実現するか書きます。

実践

まずは完成形から。
コードの仕様は以下の通りです。

  1. 標準入力がターミナルの場合、固定文と引数を出力する。
  2. 標準入力がファイルの場合、固定文とファイルの中身を出力する。
例)
$ go run main.go hoge fuga
from terminal
[hoge fuga]
$ go run main.go < test.txt
from not terminal
111
222
333
package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"syscall"

	"golang.org/x/crypto/ssh/terminal"
)

func main() {
	if terminal.IsTerminal(syscall.Stdin) {
		fmt.Println("from terminal")
		fmt.Println(os.Args[1:])
	} else {
		fmt.Println("from not terminal")
		b, err := ioutil.ReadAll(os.Stdin)
		if err != nil {
			fmt.Println(err)
			os.Exit(0)
		}
		fmt.Println(string(b))
	}
}

今回、標準入力がターミナルかどうかを判定する肝となるのはterminal.IsTerminal(syscall.Stdin)の部分です(GoDoc)。
引数に対象となるファイルディスクリプタの番号をしていることによりファイルディスクリプタがターミナルかどうか判定してくれます。
標準入力のファイルディスクリプタの数値は固定で0なのでそれを指定します。

終わりに

過去に以下のような記事も投稿しています。一つ一つは簡単なことですが、これらの要素を組み合わせることにより自らの望むツールの実現に繋がるのでごましお程度に覚えといてください。
Goでエスケープシーケンスを扱う(文字色、カーソル移動)
Goでターミナルのサイズに合わせて枠を表示し続ける

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?