getpass – パスワードのために入力文字を表示しないプロンプト

目的:コンソールに入力した文字を表示しないプロンプト、普通はパスワード入力に使用する
利用できるバージョン:1.5.2

ターミナルを通してユーザと対話的にやり取りする多くのプログラムで、スクリーン上にユーザが入力した文字を表示せずにパスワードを尋ねる必要があります。 getpass モジュールは、そういったセキュアなパスワードプロンプトを扱う移植性の高い方法を提供します。

サンプル

getpass() 関数はプロンプトを表示して、改行キーを入力するまでユーザからの入力を読み込みます。その入力は呼び出し側へ文字列として渡されます。

import getpass

p = getpass.getpass()
print 'You entered:', p

呼び出し側で何も指定しなければ、デフォルトプロンプトは “Password:” です。

$ python getpass_defaults.py
Password:
You entered: sekret

プロンプトはプログラムに応じて任意の文字列に変更できます。

import getpass

p = getpass.getpass(prompt='What is your favorite color? ')
if p.lower() == 'blue':
    print 'Right.  Off you go.'
else:
    print 'Auuuuugh!'

私はこのような安全ではない認証スキームを推奨しませんが、これはプロンプトが変更できることを説明します。

$ python getpass_prompt.py
What is your favorite color?
Right.  Off you go.
$ python getpass_prompt.py
What is your favorite color?
Auuuuugh!

デフォルトでは、 getpass() はプロンプトの文字列を表示するのに標準出力を使用します。 sys.stdout へ便利な出力を生成する可能性のあるプログラムには sys.stderr のような別のストリームからプロンプトを送ると良いです。

import getpass
import sys

p = getpass.getpass(stream=sys.stderr)
print 'You entered:', p

この方法は、パスワードプロンプトを表示せずに標準出力が(パイプかファイルへ)リダイレクトされます。それでもユーザが入力した文字はスクリーンへエコーバックされません。

$ python getpass_stream.py >/dev/null
Password:

ターミナル無しで getpass を使用する

Unix 環境では、 getpass() はターミナル経由で制御できる tty を常に必要とするので表示を無効にできます。これは非ターミナルストリームから標準入力へリダイレクトしてもその入力文字が読み込まれないことになります。

$ echo "sekret" | python getpass_defaults.py
Traceback (most recent call last):
 File "getpass_defaults.py", line 34, in
   p = getpass.getpass()
 File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/getpass.py", line 32, in unix_getpass
   old = termios.tcgetattr(fd)     # a copy to save
termios.error: (25, 'Inappropriate ioctl for device')

入力ストリームが tty ではないときは呼び出し側で検出して、そのときは代替方法で読み込みます。

import getpass
import sys

if sys.stdin.isatty():
    p = getpass.getpass('Using getpass: ')
else:
    print 'Using readline'
    p = sys.stdin.readline().rstrip()

print 'Read: ', p

tty なら次のようになります。

$ python ./getpass_noterminal.py
Using getpass:
Read:  sekret

tty ではないときは次のようになります。

$ echo "sekret" | python ./getpass_noterminal.py
Using readline
Read:  sekret

See also

getpass
本モジュールの標準ライブラリドキュメント
readline
対話的なプロンプトライブラリ
Bookmark and Share