首页 文章

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

提问于
浏览
301

我有一个脚本可以自动执行需要访问受密码保护的系统的进程 . 通过命令行程序访问系统,该程序接受用户密码作为参数 .

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

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

有人能帮忙吗?

7 回答

  • 67

    使用stty关闭 echo ,然后再打开 .

  • 460

    这是另一种方法:

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

    read -s 将为您关闭回声 . 只需将最后一行的 echo 替换为您要运行的命令即可 .

  • 3

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

    #!/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 ...
    
  • 41

    一个班轮:

    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
    
  • -3

    首先,如果有人要在文件中存储任何密码 . 我会确保它是哈希的 . 它不是最好的安全性,但至少它不会是纯文本 .

    • 首先创建密码并对其进行哈希:

    echo“password123”| md5sum | cut -d' - ' - f 1> / tmp / secret

    • 现在创建程序以使用散列,在这种情况下,这个小程序接收用户输入的密码而不回显,然后将其转换为散列以与存储的散列进行比较 . 如果它与存储的哈希匹配,则授予访问权限:

    #!/斌/庆典

    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
    
  • 149

    我发现 askpass 命令很有用

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

    每个输入字符都替换为* . 请参阅:提供密码****

  • 7
    #!/bin/bash
    stty -echo
    printf "Password: "
    read PASSWORD
    stty echo
    printf "\n"
    

相关问题