あらまし
コマンドライン入力ツールを作る際にHTMLのパスワードフォームのようにパスワード入力時に、*
を表示させたい。
何も表示しない方法は結構記事があるが、代替文字を表示させるケースはなかったので作ってみた。
実装
irb でさくっと実行可能。
irb(main):001:0> require 'io/console'
irb(main):002:0> STDIN.noecho{ |io| s = ""; loop do c = STDIN.raw(&:getc); break if c == "\r"; s += c; putc '*'; end; s}
********=> "abcdefgh"
解説
コード中にインラインで解説を記述した。
STDIN.noecho{ |io| # エコーバックを無効化して、文字を表示されないようにする。
s = ""
loop do
c = STDIN.raw(&:getc) # rawモードでgetcを呼ぶ
break if c == "\r" # Enterで入力終了とする
s += c
putc '*' # 代替文字を表示する
end
s
}
raw モードを使用することで、入力のバッファリングを無効化できる。
使用しないと、Enterキーが押されるまで入力がバッファリングされるため、代替文字がすぐに出てこない。
一方で、rawモードではCtrl-CやCtrl-Dなどが無効化されるので、
きちんとEnterキーなどで終了できるようにしておかないと、別ターミナルからkillするはめになるので注意。
課題
バッファリングがないため、バックスペースもそのままASCII コードの0x08
で入ってくる。
STDINのエンコーディングにもよるが、筆者の環境では\u007F
として扱われてしまっていた。
このあたりはうまく積んである文字列を削るなどする必要がある。
まとめ
パスワード入力時に代替文字を表示させる方法を記載した。
参考
http://qiita.com/ksss/items/9c8a237f452cd8aa7c11
http://qiita.com/mirakui/items/88194612bb0fa705e39d
http://qiita.com/kozy4324/items/6cf6deaa6440667733e3