LoginSignup
5
2

【Golang】標準入力から1文字のキー入力を読み込む(enter いらずの On KeyPress/KeyDown っぽいやつ)

Last updated at Posted at 2021-03-15

Go言語で標準入力のキー押下(KeyPress)を検知する

Golang で標準入力から1行ごとではなく、1文字だけ取得する方法を知りたい。

正確には TTY からの標準入力を 1 文字欲しいのです。Javascript で言うところの onkeypress のキーイベントを取得したいのです。

つまり、ターミナルやコマンドラインなどのユーザー入力(標準入力)で y -> enter でなく、y キーを押しただけで y を検知したいのです。

「golang 標準入力 1文字 読み込む」で Qiita 記事に絞ってググっても、競プロの課題にあるような「改行区切りで得られた文字列から、最初の文字を取得する」ような例やパイプ渡しの例ばかりだったので、自分のググラビリティとして。

TL; DR (今北産業)

  1. こういうこと 👇 をしたい人向け

    $ go run . <enter>
    Key press => a
    Key press => b
    Key press => c
    Key press => d
    ...(ctrl+c)
    signal: interrupt
    
  2. @mattn さんの素晴らしい github.com/mattn/go-tty パッケージの tty.ReadRune() を使う。

    (こいつやー!と思ったらスターを付けましょう)

  3. tty 入力を監視し、1 文字(rune)検知するごとにゴニョゴニョする。

TS; DR (マスター、動くものをくれ)

main.go
package main

import (
	"fmt"
	"log"

	"github.com/mattn/go-tty"
)

func main() {
	tty, err := tty.Open()
	if err != nil {
		log.Fatal(err)
	}

	defer tty.Close()

	fmt.Println("Ready. Press any key ...")

	for {
		r, err := tty.ReadRune()
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println("Key press => " + string(r))
	}
}

Go Playground では tty からの標準入力のテストができないため、再現性のために Dockerfile も置いておきます。

go.mod
module sample/tty

go 1.16

require github.com/mattn/go-tty v0.0.3
Dockerfile
FROM golang:1.16-alpine

COPY . /app
WORKDIR /app
RUN go mod tidy
macOS,Linuxのターミナル(要Docker)
$ # ファイルの確認
$ tree .
.
├── Dockerfile
├── go.mod
└── main.go

0 directories, 2 files

$ # 実行環境(コンテナ・イメージ)のビルド
$ docker build --tag sample/tty .
...

$ # `go run .` と同じことをコンテナ内で実行
$ docker run --rm --interactive --tty sample/tty go run .
Ready. Press any key ...
Key press => a
Key press => b
Key press => c
Key press => d
Key press => e
(ctrl+c)
signal: interrupt
$

macOS とラズパイ3+B(Raspbian GNU/Linux 9, stretch)の Docker で動きました。また、Docker 内で darwinarm 向けに静的ビルドすれば、ビルドしたバイナリをエクスポートしてローカルで実行しても動きました。

5
2
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
5
2