如何从shell脚本获取密码而不进行回显

我有一个脚本能够自动执行须要访问受密码保护的系统的进程。 经过命令行程序访问系统,该程序接受用户密码做为参数。 html

我想提示用户键入他们的密码,将其分配给shell变量,而后使用该变量构建访问程序的命令行(这固然会产生我将处理的流输出)。 程序员

我是Bourne / Bash中一个至关称职的shell程序员,但我不知道如何接受用户输入而不让它回显到终端(或者可能使用'*'字符回显)。 shell

有人能帮忙吗? 小程序


#1楼

一个班轮: 安全

read -s -p "Password: " password

在Linux(和cygwin)下,这个表单适用于bash和sh。 但它可能不是标准的Unix sh。 bash

有关更多信息和选项,请在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

#2楼

-s的选项read未在POSIX标准定义。 请参见http://pubs.opengroup.org/onlinepubs/9699919799/utilities/read.html 。 我想要一些适用于任何POSIX shell的东西,因此我编写了一个使用stty来禁用echo的小函数。 spa

#!/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命令。 code

[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 ...

#3楼

首先,若是有人要在文件中存储任何密码,我会确保它已经散列。 这不是最好的安全性,但至少它不会是纯文本。

  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

#4楼

使用stty关闭echo ,而后再从新打开。


#5楼

符合POSIX的答案。 注意使用/bin/sh而不是/bin/bash 。 (它确实与bash一块儿使用,但它不须要 bash。)

#!/bin/sh
stty -echo
printf "Password: "
read PASSWORD
stty echo
printf "\n"
相关文章
相关标签/搜索