6

Как получить пароль из оболочки без вывода в терминал?

11

У меня есть скрипт, который автоматизирует процесс и требует доступа к защищенной паролем системе. Доступ к системе осуществляется через командную программу, которая принимает пароль пользователя в качестве аргумента.

Я хотел бы запросить у пользователя ввод пароля, присвоить его переменной оболочки и затем использовать эту переменную для формирования командной строки программы доступа (которая, разумеется, будет выводить данные в поток, который я буду обрабатывать).

Я довольно неплохо разбираюсь в программировании на оболочке Bourne/Bash, но не знаю, как принять ввод от пользователя так, чтобы он не отображался в терминале (или чтобы отображался с использованием символов '*').

Может быть, кто-то сможет мне помочь?

5 ответ(ов)

3

Вот POSIX-совместимый ответ. Обратите внимание на использование /bin/sh вместо /bin/bash. Скрипт работает и с bash, но не требует его.

#!/bin/sh
stty -echo
printf "Пароль: "
read PASSWORD
stty echo
printf "\n"

Этот скрипт временно отключает вывод символов на экран при вводе пароля, а затем снова включает его.

1

Однострочник для ввода пароля без отображения:

read -s -p "Пароль: " password

Этот подход работает в bash и sh под Linux (и Cygwin). Однако может не поддерживаться стандартным Unix sh.

Для получения дополнительной информации и параметров в bash введите "help read".

$ help read
read: read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
Считывает строку из стандартного ввода и разбивает ее на поля.
  ...
  -p prompt выводит строку PROMPT без завершающего перевода строки перед попыткой считывания
  ...
  -s                не выводить ввод, поступающий из терминала
0

Опция -s команды read не определена в стандарте POSIX. Для подробной информации посмотрите документацию. Поскольку я хотел, чтобы решение работало в любом POSIX-совместимом шелле, я написал небольшую функцию, которая использует stty для отключения эха.

# Чтение секретной строки
read_secret() {
    # Устанавливаем trap, чтобы гарантировать, что эхо будет включено перед выходом,
    # если скрипт завершится, пока эхо отключено.
    trap 'stty echo' EXIT

    # Отключаем эхо.
    stty -echo

    # Читаем секрет.
    read "$@"

    # Включаем эхо.
    stty echo
    trap - EXIT

    # Печатаем новую строку, так как нажатая пользователем клавиша Enter
    # не отображается. Это гарантирует, что следующая строка вывода начнётся с новой строки.
    echo
}

Эта функция работает очень похоже на команду read. Вот простой пример использования read, за которым следует подобное использование read_secret. Ввод для read_secret кажется пустым, потому что он не отображается в терминале.

[susam@cube ~]$ read a b c
foo \bar baz \qux
[susam@cube ~]$ echo a=$a b=$b c=$c
a=foo b=bar c=baz qux
[susam@cube ~]$ unset a b c
[susam@cube ~]$ read_secret a b c

[susam@cube ~]$ echo a=$a b=$b c=$c
a=foo b=bar c=baz qux
[susam@cube ~]$ unset a b c

Вот ещё один пример, который использует опцию -r, чтобы сохранить обратные слэши во вводе. Это работает, потому что функция read_secret, как показано выше, передаёт все аргументы, которые она получает, команде read.

[susam@cube ~]$ read -r a b c
foo \bar baz \qux
[susam@cube ~]$ echo a=$a b=$b c=$c
a=foo b=\bar c=baz \qux
[susam@cube ~]$ unset a b c
[susam@cube ~]$ read_secret -r a b c

[susam@cube ~]$ echo a=$a b=$b c=$c
a=foo b=\bar c=baz \qux
[susam@cube ~]$ unset a b c

Наконец, вот пример, который демонстрирует, как использовать функцию read_secret для чтения пароля в соответствии с требованиями POSIX.

printf "Пароль: "
read_secret password
# Сделайте что-то с $password здесь ...
0

Использование команды askpass действительно может быть очень полезным. Вот пример, как её можно применить для запроса пароля:

password=$(/lib/cryptsetup/askpass "Введите пароль")

При этом каждое введенное вами символ будет заменено на *, что обеспечивает дополнительную безопасность. Например, если ввести пароль "1234", в интерфейсе вы увидите:

Введите пароль ****

Таким образом, askpass помогает скрыть вводимый пароль от посторонних глаз.

0

Вы также можете запросить пароль, не устанавливая переменную в текущей оболочке, используя следующий синтаксис:

$(read -s;echo $REPLY)

Например, это можно использовать так:

my-command --set password=$(read -sp "Пароль: ";echo $REPLY)

Вы также можете добавить несколько запрашиваемых значений с переводом строки, сделав это следующим образом:

my-command --set user=$(read -sp "`echo $'\n '`Пользователь: ";echo $REPLY) --set password=$(read -sp "`echo $'\n '`Пароль: ";echo $REPLY)

Этот подход позволяет вводить значения без отображения введенных символов.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь