Как получить пароль из сценария оболочки, не повторяя

319

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

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

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

Может ли кто-нибудь помочь с этим?

Теги:
sh
scripting

8 ответов

478
Лучший ответ

Вот еще один способ сделать это:

#!/bin/bash
# Read Password
echo -n Password: 
read -s password
echo
# Run Command
echo $password

read -s отключит эхо для вас. Просто замените echo на последней строке командой, которую вы хотите запустить.

  • 75
    Некоторые оболочки позволяют указать приглашение для команды read : read -s -p "Password:" password
  • 32
    Обратите внимание, что read -s отсутствует в POSIX, ваш скрипт зависит от bash, если вы его используете. Если вы хотите быть POSIX-совместимым, вы должны вместо этого использовать решение stty -echo предложенное ниже, потому что stty и его параметр echo определены в POSIX.
Показать ещё 5 комментариев
162
#!/bin/bash
stty -echo
printf "Password: "
read PASSWORD
stty echo
printf "\n"
  • 0
    @RichardRiley - если вы имеете в виду «читать ПАРОЛЬ», это правильно?
  • 1
    Первоначально был принят как лучшее решение и использовался в сценарии, который я писал, но пароль «read -s -p»: «PASSWORD» кажется намного проще.
Показать ещё 3 комментария
69

Один вкладыш:

read -s -p "Password: " password

В Linux (и cygwin) эта форма работает в bash и sh. Однако это может быть не стандартная 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 ...]
Read a line from the standard input and split it into fields.
  ...
  -p prompt output the string PROMPT without a trailing newline before
            attempting to read
  ...
  -s                do not echo input coming from a terminal
  • 1
    Если команда генерирует «следующим образом: Illegal опция -s» это означает , что сценарий должен быть выполнен непосредственно (./script против ш ./script) ... см stackoverflow.com/questions/30554353/...
45

Опция -s read не определена в стандарте POSIX. См. http://pubs.opengroup.org/onlinepubs/9699919799/utilities/read.html. Я хотел что-то, что будет работать для любой оболочки POSIX, поэтому я написал небольшую функцию, которая использует stty для отключения эха.

#!/bin/sh

# Read secret string
read_secret()
{
    # Disable echo.
    stty -echo

    # Set up trap to ensure echo is enabled before exiting if the script
    # is terminated while echo is disabled.
    trap 'stty echo' EXIT

    # Read secret.
    read "$@"

    # Enable echo.
    stty echo
    trap - EXIT

    # Print a newline because the newline entered by the user after
    # entering the passcode is not echoed. This ensures that the
    # next line of output begins at a new line.
    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 "Password: "
read_secret password
# Do something with $password here ...
  • 6
    Вероятно, следует убедиться, что echo еще не отключен в оболочке, и не включать его, если он не был раньше ... Возможно, используйте oldtty = stty -g и затем в конце stty $oldtty для восстановления предыдущих настроек. В противном случае это здорово.
9

Я нашел команду askpass полезной

password=$(/lib/cryptsetup/askpass "Give a password")

Каждый входной символ заменяется на *. Видеть: Введите пароль ****

  • 1
    Откуда этот /lib/cryptsetup/askpass ? Это, конечно, не стандартный * nix (или GNU / Linux) инструмент.
  • 0
    Это лучшее решение, которое я видел до сих пор. Это от cryptsetup, который является стандартом для шифрования жестких дисков, поэтому довольно часто используется. sudo apt-get install cryptsetup .
Показать ещё 3 комментария
3

Отключите echo, используя stty, затем снова включитесь после.

-2

Прежде всего, если кто-то собирается сохранить какой-либо пароль в файле, я бы позаботился о том, чтобы он хэшировался. Это не лучшая безопасность, но, по крайней мере, она не будет в текстовом виде.

  1. Сначала создайте пароль и хэшируйте его:

    echo "password123" | md5sum  | cut -d '-' -f 1 > /tmp/secret
    
  2. Теперь создайте свою программу для использования хэша. В этом случае эта небольшая программа получает вводимые пользователем данные для ввода пароля без повторения, а затем преобразует их в хеш-код для сравнения с сохраненным хеш-кодом. Если он соответствует сохраненному хешу, доступ предоставляется:

    #!/bin/bash
    
    PASSWORD_FILE="/tmp/secret"
    MD5_HASH=$(cat /tmp/secret)
    PASSWORD_WRONG=1
    
    
    while [ $PASSWORD_WRONG -eq 1 ]
     do
        echo "Enter your password:"
        read -s ENTERED_PASSWORD
        if [ "$MD5_HASH" != "$(echo $ENTERED_PASSWORD | md5sum | cut -d '-' -f 1)" ]; then
            echo "Access Deniend: Incorrenct password!. Try again"
        else
            echo "Access Granted"
            PASSWORD_WRONG=0
        fi
    done
    
  • 1
    Я предлагаю сохранить символ новой строки \n вызванный командой echo от хеширования, используя вместо этого echo -n , поскольку \n самом деле не является частью предоставленного пароля - конечно, как для создания /tmp/secret и для сравнения, которое следует после в вашем примере.
  • 0
    Вопрос ничего не говорил о сохранении в файл.
-5
echo yourpassword | passwd --stdin youruser

Ещё вопросы

Сообщество Overcoder
Наверх
Меню