2010-10-20 168 views
243

我有一个脚本可以自动执行需要访问密码保护系统的进程。系统通过一个接受用户密码作为参数的命令行程序来访问。如何从shell脚本获取密码而不回显

我想提示用户输入他们的密码,将其分配给shell变量,然后使用该变量构造访问程序的命令行(这当然会产生流输出,我将处理)。我是Bourne/Bash的一名合理的shell编程人员,但我不知道如何接受用户输入而不会回应到终端(或者可能会使用'*'字符回显)。

任何人都可以帮忙吗?

+1

可能重复[如何使bash脚本要求输入密码?](http://stackoverflow.com/questions/2654009/how-to-make-bash-script -ask-for-a-password) – 2015-02-14 10:23:42

回答

373

这里是另一种方式来做到这一点:

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

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

+56

有些shell允许你指定'读命令:'读-s -p“密码:”密码“ – 2010-10-20 19:40:05

+5

我绝对更喜欢'读-s -p',很多感谢简化我的脚本。 – 2013-02-05 21:05:01

+25

请注意,'read -s'不在POSIX中,如果你使用它,你的脚本依赖于bash。如果你想符合POSIX标准,你应该使用下面建议的'stty -echo'解决方案,因为'stty'及其''echo'参数在POSIX中定义。 – scy 2014-01-22 11:28:51

3

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

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

@RichardRiley - 假设你的意思是“read -s密码”,这是正确的吗? – 2013-02-05 20:58:08

+0

最初被接受为最佳解决方案,并在我正在编写的脚本中使用,但是“read -s -p”密码:“PASSWORD”似乎简单得多。 – 2013-02-05 21:04:08

+38

不,真的,如果你想符合POSIX标准,_do_使用'stty'。这个答案中的代码甚至不在bash中运行,但实际上在符合POSIX的_all_ shell上运行。 – scy 2014-01-22 11:33:24

57

一个内胆:

read -s -p "Password: " password 

在Linux(和Cygwin)这种形式在bash和sh工作。不过,它可能不是标准的Unix sh。

欲了解更多信息和选项,请在bash中输入“帮助阅读”。

$ 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-非法选项读取-a – 2015-12-24 15:40:04

-4
echo yourpassword | passwd --stdin youruser 
33

read-s选项未在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_secretread_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

应该确保echo在shell中没有被禁用,并且如果它不在之前就不启用它......可以使用'oldtty = stty -g'然后在最后' stty $ oldtty'恢复以前的设置。否则,这很好。 – Perkins 2016-04-01 05:33:59

-3

首先,如果有人打算在文件中存储任何密码。我会确保它被散列。这不是最好的安全性,但至少它不会是明文的。

  1. 首先创建密码散列和它:

    回声 “password123” | md5sum |现在创建你的程序来使用散列,在这种情况下,这个小程序接收用户输入的密码而不回显,然后将其转换为哈希以便将其转换为散列与存储的散列进行比较。 !如果存储的哈希则访问匹配:

    #/斌/庆典

    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 -n'将'echo'命令产生的换行字符'\ n'避开哈希值 - 当然, '/ tmp/secret'和你的例子中的比较。 – 2016-10-12 10:23:13

2

我发现是在askpass命令有用

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

每个输入字符被*替换。请参阅: 给出一个密码****

+0

这个'/ lib/cryptsetup/askpass'从哪里来?这当然不是标准的* nix(或GNU/Linux)工具。 – 2017-06-19 19:13:58

+0

这是迄今为止我见过的最好的解决方案。它来自cryptsetup,这是加密硬盘驱动器的标准,非常常用。 'sudo apt-get install cryptsetup'。 – 2017-07-08 15:18:32

+0

我试过用这个,星星没有出现,再加上它弄乱了我的终端大时间,直到我关闭它。任何进一步的shell输入被隐藏! – Jeff 2018-01-19 14:12:04

相关问题