2010-10-20 3 views
243

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

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

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

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

+1

Возможный дубликат [Как сделать скрипт bash запросить пароль?] (Http://stackoverflow.com/questions/2654009/how-to-make-bash-script -ask-for-a-password) –

ответ

373

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

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

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

+56

Некоторые оболочки позволяют вам указать приглашение для ' read': 'read -s -p 'Пароль:« password » –

+5

Я определенно предпочитаю« читать -s -p », большое спасибо за упрощение моих скриптов. –

+25

Обратите внимание: что 'read -s' не находится в POSIX, ваш скрипт зависит от bash, если вы его используете. Если вы хотите быть совместимым с POSIX, вместо этого вы должны использовать предложенное ниже решение 'stty -echo', потому что' stty' и его параметр 'echo' определены в POSIX. – scy

3

Поверните echo с помощью stty, затем снова включите его после.

124
#!/bin/bash 
stty -echo 
printf "Password: " 
read PASSWORD 
stty echo 
printf "\n" 
+0

@RichardRiley - если вы имеете в виду «read -s PASSWORD» здесь, это правильно? –

+0

Первоначально принятое как лучшее решение и используемое в скрипте, который я писал, но «read -s -p» password: «PASSWORD» кажется намного проще. –

+38

Нет, действительно, _do_ используйте 'stty', если вы хотите быть совместимым с POSIX. Код в этом ответе отлично работает даже не в bash, а фактически на _all_ оболочках, которые соответствуют POSIX. – scy

57

Один лайнер:

read -s -p "Password: " password 

Под 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 ...] 
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

Если команда генерирует «read: Illegal option -s», это означает, что скрипт должен выполняться напрямую (./script vs sh ./script) ... см. Http://stackoverflow.com/questions/30554353/linux- незаконно-option-read-a –

-4
echo yourpassword | passwd --stdin youruser 
33

-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 "[email protected]" 

    # 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 пуст, потому что он не был отозван на терминал.

[[email protected] ~]$ read a b c 
foo \bar baz \qux 
[[email protected] ~]$ echo a=$a b=$b c=$c 
a=foo b=bar c=baz qux 
[[email protected] ~]$ unset a b c 
[[email protected] ~]$ read_secret a b c 

[[email protected] ~]$ echo a=$a b=$b c=$c 
a=foo b=bar c=baz qux 
[[email protected] ~]$ unset a b c 

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

[[email protected] ~]$ read -r a b c 
foo \bar baz \qux 
[[email protected] ~]$ echo a=$a b=$b c=$c 
a=foo b=\bar c=baz \qux 
[[email protected] ~]$ unset a b c 
[[email protected] ~]$ read_secret -r a b c 

[[email protected] ~]$ echo a=$a b=$b c=$c 
a=foo b=\bar c=baz \qux 
[[email protected] ~]$ unset a b c 

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

printf "Password: " 
read_secret password 
# Do something with $password here ... 
+3

Должно быть, убедитесь, что эхо не отключено в оболочке и не активировано, если оно не было раньше ... Возможно, вы можете использовать 'oldtty = stty -g', а затем в конце' stty $ oldtty' для восстановления предыдущих настроек. В противном случае это здорово. – Perkins

-3

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

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

    эхо "password123" | md5sum | cut -d '-' -f 1>/tmp/secret

  2. Теперь создайте свою программу для использования хэша, в этом случае эта небольшая программа получает вход пользователя для пароля без эха и затем преобразует его в хеш по сравнению с сохраненным хешем. Если он соответствует сохраненной хэш затем предоставлен доступ:

    #/bin/Баш

    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' и сравнение, которое следует в вашем примере. –

2

я нашел, чтобы быть askpass команда полезна

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

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

+0

Где этот '/ lib/cryptsetup/askpass'? Это, конечно, не стандартный инструмент * nix (или GNU/Linux). –

+0

Это лучшее решение, которое я видел до сих пор.Это от cryptsetup, который является стандартом для шифрования жестких дисков, поэтому довольно часто используется. 'sudo apt-get install cryptsetup'. –

+0

Я попытался использовать это, и звезды не появлялись, плюс это испортило мой терминал большое время, пока я его не закрыл. Любой дополнительный ввод оболочки скрыт! – Jeff