Запрос Python для пользователя с эхом и паролем без эха
Следуя подсказкам кода для пользователя и пароля, при запуске в консоли:
import getpass
user = getpass.getpass("Username:")
passwd = getpass.getpass("Password for " + user + ":")
print "Got", user, passwd
Очевидная проблема, описанная выше, заключается в том, что имя пользователя не отражается по мере ее ввода.
Теперь getpass
документации: "В Unix по умолчанию используется /dev/tty, прежде чем вернуться к sys.stdin и sys.stderr".
Вопрос: Как задать имя пользователя и пароль, чтобы они были прочитаны из одного источника, а имя пользователя выбрано нормально, а пароль - нет?
Ответы
Ответ 1
Есть еще одна альтернатива, которую я нашел задокументированной здесь. Определите, является ли поток ввода TTY, и измените метод ввода на основе этой информации.
Я использовал что-то вроде этого:
#!/usr/bin/python
import sys
import getpass
if sys.stdin.isatty():
print "Enter credentials"
username = raw_input("Username: ")
password = getpass.getpass("Password: ")
else:
username = sys.stdin.readline().rstrip()
password = sys.stdin.readline().rstrip()
print "Username: [%s], password [%s]" % (username, password)
Это нормально работает с терминала:
bash> ./mytest.py
Enter credentials
Username: one
Password:
Username: [one], password [two]
для ввода по каналу:
bash> echo "one
> two" | ./mytest.py
Username: [one], password [two]
для ввода из файла:
bash> echo "one" > input
bash> echo "two" >> input
bash> ./mytest.py < input
Username: [one], password [two]
а также для наследственника:
bash> ./mytest.py << EOF
> one
> two
> EOF
Username: [one], password [two]
Лично это покрывает все мои потребности.
Ответ 2
Почему бы просто не использовать raw_input
для имени пользователя:
import getpass
user = raw_input("Username:")
passwd = getpass.getpass("Password for " + user + ":")
print("Got", user, passwd)
Демо-версия:
Username:iCodez
Password for iCodez:
('Got', 'iCodez', 'secret')
Ответ 3
В Python 2.x используйте raw_input
(input
в Python 3.x) вместо getpass.getpass
для имени пользователя.
user = raw_input("Username:")
Ответ 4
Можно было бы использовать raw_input
(input
в Python 3), но, как уже упоминалось в вопросе, getpass
использует /dev/tty, прежде чем вернуться к sys.stdin и sys.stderr. Это означает, что в некоторых ситуациях getpass
и raw_input
используют разные источники.
В linux вы можете увидеть разницу, выполнив приложение с помощью следующей команды:
my_app.py < /path/to/some/file
Функция raw_input
будет считывать из файла, а getpass
все равно будет использовать терминал. Даже если это не задокументировано явно, то же самое происходит и в Windows.
Я не нашел функцию, которая делает что-то вроде getpass
без скрытия ввода. Я думаю, вы должны реализовать его самостоятельно или искать библиотеку, которая это делает. Вы можете посмотреть текущую реализацию getpass
в Python 3 и Python 2.7, чтобы получить вдохновение.
Я написал текст ниже. В основном, я использовал реализацию Python 3 и удалил все, что связано со скрытием ввода. Затем я внес некоторые изменения в поддержку Python 2.
def _raw_input(prompt, fin, fout):
if prompt:
try:
fout.write(prompt)
except UnicodeEncodeError:
# Replace characters that are not supported by the terminal
prompt = prompt.encode(fout.encoding, 'replace')
prompt = prompt.decode(fout.encoding)
fout.write(prompt)
fout.flush()
line = fin.readline()
return line[:-1] if line[-1] == '\n' else line
def _ttyinput_unix(prompt):
try:
fd = os.open("/dev/tty", os.O_RDWR, os.O_NOCTTY)
if sys.version_info < (3, 0):
with os.fdopen(fd, 'w+', 1) as tty:
return _raw_input(prompt, tty, tty)
with io.FileIO(fd, 'w+') as tty:
with io.TextIOWrapper(tty) as wrapper:
return _raw_input(prompt, wrapper, wrapper)
except (OSError, AttributeError) as e:
return _raw_input(prompt, sys.stdin, sys.stderr)
def _ttyinput_win(prompt):
if sys.stdin is not sys.__stdin__:
# I don't know why getpass is doing this.
return _raw_input(prompt, sys.stdin, sys.stderr)
if sys.version_info >= (3, 0):
getch = msvcrt.getwch
putch = msvcrt.putwch
else:
getch = msvcrt.getch
putch = msvcrt.putch
for c in prompt:
putch(c)
password = ""
while True:
c = getch()
if c == '\r' or c == '\n':
break
if c == '\003':
raise KeyboardInterrupt
if c == '\b':
if len(password) > 0:
password = password[:-1]
for x in "\b \b":
putch(x)
else:
password += c
putch(c)
putch('\r')
putch('\n')
return password
try:
import msvcrt
ttyinput = _ttyinput_win
except ImportError:
ttyinput = _ttyinput_unix
Я протестировал свою реализацию с Python 2.7 на Windows и с Python 2.7 и 3.5 на Arch Linux.
Ответ 5
попробуй это:
user = raw_input("Username:")