- GitHub / ruby / ruby / ruby_1_8 / lib / net / imap.rb # get_password ※1
- Qiita
- mirakui / 2012-12-11: パスワード等の標準入力を隠す ※2
- kozy4324 / 2015-01-29: パスワード等の標準入力を隠す(プロンプトを出力しながら) ※3
Ruby 1.8 世代の古いやり方だと gets 前後で Kernel.#system から stty (1) を呼び -echo と echo で囲むというやり方が行われており net/imap の中でも使われていた(※1)。
gem が使える場合には highline って方法もあるようだが、gem を入れるのにひと手間必要(※2)。
標準添付ライブラリの readline を使う方法もあるようだが、自前でビルドした際にはしばしば GNU readline を入れ忘れている場合がある(※3)。
2016-02-03 現在だと、
Ruby 1.9.3 preview1 以降で追加された標準添付ライブラリ io/console(code) が提供している IO#noecho を使うのが多分一番手軽で標準的な方法のようだ(※2, ※3)。
以下の様な感じ
ただし、highline だとリアルタイムに入力を * で隠すとか出来るみたいなんだけど、
上記 IO#noecho の例だと入力は全く見えない。
これは OpenSSH なんかも、IO#noecho と同じように何も表示されないので、まぁ仕方ないかって感じ。
標準添付ライブラリ io/console が提供している IO#getch を使うと1文字毎にインタラクト出来るので * でマスクとかも出来なくはないんだけど、F1 で \e[OP とか、DEL で \e[3~ とかの可変長エスケープシーケンスが1文字ずつ返ってくる上、Ctrl-c とかも食えちゃうのであまり楽な処理が出来ない。
例えばエスケープシーケンス無視してもこんな感じになる。Gem にするならともかく、これをソースに埋め込むのは実に野暮ったい。
gem が使える場合には highline って方法もあるようだが、gem を入れるのにひと手間必要(※2)。
標準添付ライブラリの readline を使う方法もあるようだが、自前でビルドした際にはしばしば GNU readline を入れ忘れている場合がある(※3)。
2016-02-03 現在だと、
Ruby 1.9.3 preview1 以降で追加された標準添付ライブラリ io/console(code) が提供している IO#noecho を使うのが多分一番手軽で標準的な方法のようだ(※2, ※3)。
以下の様な感じ
require 'io/console' print "Password: " password = STDIN.noecho(&:gets).chomp! puts
ただし、highline だとリアルタイムに入力を * で隠すとか出来るみたいなんだけど、
上記 IO#noecho の例だと入力は全く見えない。
これは OpenSSH なんかも、IO#noecho と同じように何も表示されないので、まぁ仕方ないかって感じ。
標準添付ライブラリ io/console が提供している IO#getch を使うと1文字毎にインタラクト出来るので * でマスクとかも出来なくはないんだけど、F1 で \e[OP とか、DEL で \e[3~ とかの可変長エスケープシーケンスが1文字ずつ返ってくる上、Ctrl-c とかも食えちゃうのであまり楽な処理が出来ない。
例えばエスケープシーケンス無視してもこんな感じになる。Gem にするならともかく、これをソースに埋め込むのは実に野暮ったい。
GitHub / kou1okada / getpw.rb
#!/usr/bin/env ruby require 'io/console' def getpw pw = c = "" begin c = STDIN.getch case c when /[\x03]/ # C-c Process.kill('SIGINT', Process.pid) when /[\x1a]/ # C-z Process.kill('SIGSTOP', Process.pid) when /[\b\x7f]/ # C-h|BS if 0 < pw.length print "\b \b" pw.chop! end when /[\x15]/ # C-u print "\b \b" * pw.length pw = "" when /[[:print:]]/ print "*" pw += c else print "*" pw += c end end until c =~ /[\r\n]/ pw end if __FILE__ == $0 print "Password: " password = getpw.chomp! puts p password end
タグ
コメントをかく