golangでUNIX系OSでパイプからの標準入力とキーボード入力を両立させる
Pocket

Golangで、パイプからの標準入力を受け付けつつ、さらにキーボードからの入力を別に受付させたいということがあった。
で、前にシェルスクリプトの場合だと/dev/ttyから受け付けすることができる、という内容について記述したことがあったが、それと同じようにすることで実現できるようだ。

Sponsored Links

● sample_keyinput_and_pipe.go

package main

import (
	"fmt"
	"io"
	"log"
	"os"
	"time"

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

func readStdin() {
	buf := make([]byte, 1024)
	for {
		n, err := os.Stdin.Read(buf)
		if err != nil && err != io.EOF {
			log.Fatal(err)
		}
		fmt.Print("FROM STDIN:", string(buf[:n]))
		if err == io.EOF {
			return
		}
	}
}

func main() {
	// 標準入力からの読み取り(goroutine)
	go readStdin()

	// 表示が混ざるので、とりあえずsleep
	time.Sleep(10 * time.Millisecond)

	// promptの出力
	fmt.Print("\nINPUT TTY:")

	// /dev/ttyを開く
	tty, err := os.Open("/dev/tty")
	if err != nil {
		log.Fatal(err)
	}
	defer tty.Close()

	// bufferにキーボードからの入力を出力
	buf := make([]byte, 1024)
	n, err := tty.Read(buf)
	if err != nil && err != io.EOF {
		log.Fatal(err)
	}
	fmt.Print("\nFROM TTY:", string(buf[:n]))

	// passwordとして扱わせる
	// promptの出力
	fmt.Print("\nINPUT TTY(Password):")
	result, err := terminal.ReadPassword(int(tty.Fd()))
	if err != nil && err != io.EOF {
		log.Fatal(err)
	}

	fmt.Print("\nFROM TTY(Password):", string(result))

}

 

使いどころはそんなになさそうだけど、標準入力を受け付けながらパスワード入力を受け付ける、などのときに役に立つだろう。
(Windowsの場合だとどうすればいいのだろう…?)

 

Pocket

Written by blacknon

インフラエンジニア(…のつもり)。 仕事で使うならクライアントはWindowsよりはUNIXの方が好き。 大体いつも眠い。

Leave a Comment

メールアドレスが公開されることはありません。

*