如何为在 bash 中提示输入的命令提供密码?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4857702/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to provide password to a command that prompts for one in bash?
提问by Nate W.
I'm writing a UNIX shell function that is going to execute a command that will prompt the user for a password. I want to hard-code the password into the script and provide it to the command. I've tried piping the password into the command like this:
我正在编写一个 UNIX shell 函数,该函数将执行一个命令,提示用户输入密码。我想将密码硬编码到脚本中并将其提供给命令。我试过将密码输入到命令中,如下所示:
function() {
echo "password" | command
}
This may not work for some commands as the command may flush the input buffer before prompting for the password.
这可能不适用于某些命令,因为该命令可能会在提示输入密码之前刷新输入缓冲区。
I've also tried redirecting standard input to a file containing the password like this, but that doesn't work either:
我也试过将标准输入重定向到一个包含这样密码的文件,但这也不起作用:
function() {
echo "password" > pass.tmp
command < pass.tmp
rm pass.tmp
}
I know that some commands allow for the password to be provided as an argument, but I'd rather go through standard input.
我知道有些命令允许将密码作为参数提供,但我宁愿通过标准输入。
I'm looking for a quick and dirty way of piping a password into a command in bash.
我正在寻找一种快速而肮脏的方式将密码输入 bash 中的命令。
采纳答案by SiegeX
回答by Eric Leschinski
How to use autoexpect to pipe a password into a command:
如何使用 autoexpect 将密码通过管道传输到命令中:
These steps are illustrated with an Ubuntu 12.10 desktop. The exact commands for your distribution may be slightly different.
这些步骤以 Ubuntu 12.10 桌面为例。您的发行版的确切命令可能略有不同。
This is dangerous because you risk exposing whatever password you use to anyone who can read the autoexpect script file.
这是危险的,因为您可能会将您使用的任何密码暴露给可以读取 autoexpect 脚本文件的任何人。
DO NOT expose your root password or power user passwords by piping them through expect like this. Root kits WILL find this in an instant and your box is owned.
不要通过像这样通过管道传输您的 root 密码或高级用户密码来暴露它们。Root kits 会立即找到它,并且您的盒子已经拥有。
EXPECT spawns a process, reads text that comes in then sends text predefined in the script file.
EXPECT 生成一个进程,读取传入的文本,然后发送脚本文件中预定义的文本。
Make sure you have
expect
andautoexpect
installed:sudo apt-get install expect sudo apt-get install expect-dev
Read up on it:
man expect man autoexpect
Go to your home directory:
cd /home/el
User
el
cannot chown a file to root and must enter a password:touch testfile.txt sudo chown root:root testfile.txt [enter password to authorize the changing of the owner]
This is the password entry we want to automate. Restart the terminal to ensure that sudo asks us for the password again. Go to /home/el again and do this:
touch myfile.txt autoexpect -f my_test_expect.exp sudo chown root:root myfile.txt [enter password which authorizes the chown to root] autoexpect done, file is my_test_expect.exp
You have created
my_test_expect.exp
file. Your super secret password is stored plaintext in this file. This should make you VERY uncomfortable. Mitigate some discomfort by restricting permissions and ownership as much as possible:sudo chown el my_test_expect.exp //make el the owner. sudo chmod 700 my_test_expect.exp //make file only readable by el.
You see these sorts of commands at the bottom of
my_test_expect.exp
:set timeout -1 spawn sudo chown root:root myfile.txt match_max 100000 expect -exact "\[sudo\] password for el: " send -- "YourPasswordStoredInPlaintext\r" expect eof
You will need to verify that the above expect commands are appropriate. If the autoexpect script is being overly sensitive or not sensitive enough then it will hang. In this case it's acceptable because the expect is waiting for text that will always arrive.
Run the expect script as user el:
expect my_test_expect.exp spawn sudo chown root:root myfile.txt [sudo] password for el:
The password contained in my_test_expect.exp was piped into a chown to root by user el. To see if the password was accepted, look at
myfile.txt
:ls -l -rw-r--r-- 1 root root 0 Dec 2 14:48 myfile.txt
确保您已安装
expect
并autoexpect
安装:sudo apt-get install expect sudo apt-get install expect-dev
阅读它:
man expect man autoexpect
转到您的主目录:
cd /home/el
用户
el
不能 chown 文件到 root 并且必须输入密码:touch testfile.txt sudo chown root:root testfile.txt [enter password to authorize the changing of the owner]
这是我们想要自动化的密码输入。重新启动终端以确保 sudo 再次要求我们输入密码。再次转到 /home/el 并执行以下操作:
touch myfile.txt autoexpect -f my_test_expect.exp sudo chown root:root myfile.txt [enter password which authorizes the chown to root] autoexpect done, file is my_test_expect.exp
您已创建
my_test_expect.exp
文件。您的超级秘密密码以明文形式存储在此文件中。这应该会让你非常不舒服。通过尽可能地限制权限和所有权来减轻一些不适:sudo chown el my_test_expect.exp //make el the owner. sudo chmod 700 my_test_expect.exp //make file only readable by el.
您会在 底部看到这些类型的命令
my_test_expect.exp
:set timeout -1 spawn sudo chown root:root myfile.txt match_max 100000 expect -exact "\[sudo\] password for el: " send -- "YourPasswordStoredInPlaintext\r" expect eof
您将需要验证上述期望命令是否合适。如果 autoexpect 脚本过于敏感或不够敏感,那么它将挂起。在这种情况下,这是可以接受的,因为期望正在等待始终到达的文本。
以 el 用户身份运行 expect 脚本:
expect my_test_expect.exp spawn sudo chown root:root myfile.txt [sudo] password for el:
包含在 my_test_expect.exp 中的密码被用户 el 通过管道传送到 root 的 chown 中。要查看密码是否被接受,请查看
myfile.txt
:ls -l -rw-r--r-- 1 root root 0 Dec 2 14:48 myfile.txt
It worked because it is root, and el never entered a password. If you expose your root, sudo, or power user password with this script, then acquiring root on your box will be easy. Such is the penalty for a security system that lets everybody in no questions asked.
它有效,因为它是 root,并且 el 从未输入过密码。如果您使用此脚本公开您的 root、sudo 或高级用户密码,那么在您的机器上获取 root 将很容易。这是对安全系统的惩罚,该系统让每个人都没有被问到的问题。
回答by Roozbeh
You can use the -S
flag to read from std input. Find below an example:
您可以使用该-S
标志从 std 输入中读取。在下面找到一个例子:
function shutd()
{
echo "mySuperSecurePassword" | sudo -S shutdown -h now
}
回答by paxdiablo
Secure commands will not allow this, and rightly so, I'm afraid - it's a security hole you could drive a truck through.
安全命令不允许这样做,我担心这是正确的 - 这是一个您可以驾驶卡车通过的安全漏洞。
If your command does not allow it using input redirection, or a command-line parameter, or a configuration file, then you're going to have to resort to serious trickery.
如果您的命令不允许使用输入重定向、命令行参数或配置文件,那么您将不得不诉诸严重的技巧。
Some applications will actually open up /dev/tty
to ensure you will have a hard time defeating security. You canget around them by temporarily taking over /dev/tty
(creating your own as a pipe, for example) but this requires serious privileges and even itcan be defeated.
某些应用程序实际上会打开/dev/tty
以确保您很难击败安全性。您可以通过临时接管来绕过它们/dev/tty
(例如,将自己的管道创建为管道),但这需要很高的权限,甚至可能会被击败。
回答by Keith
Programs that prompt for passwords usually set the tty into "raw" mode, and read input directly from the tty. If you spawn the subprocess in a pty you can make that work. That is what Expect does...
提示输入密码的程序通常将 tty 设置为“原始”模式,并直接从 tty 读取输入。如果您在 pty 中生成子进程,则可以使其工作。这就是Expect所做的......
回答by Matthias Braun
with read
和 read
Here's an example that uses read
to get the password and store it in the variable pass
. Then, 7z
uses the password to create an encrypted archive:
这是一个read
用于获取密码并将其存储在变量中的示例pass
。然后,7z
使用密码创建加密存档:
read -s -p "Enter password: " pass && 7z a archive.zip a_file -p"$pass"; unset pass
But be aware that the password can easily be sniffed.
但请注意,密码很容易被嗅探。
回答by Alex Bins
Simply use :
只需使用:
echo "password" | sudo -S mount -t vfat /dev/sda1 /media/usb/;
if [ $? -eq 0 ]; then
echo -e '[ ok ] Usb key mounted'
else
echo -e '[warn] The USB key is not mounted'
fi
This code is working for me, and its in /etc/init.d/myscriptbash.sh
这段代码对我有用,它在 /etc/init.d/myscriptbash.sh
回答by Ratinho
That's a really insecure idea, but: Using the passwd command from within a shell script
这是一个非常不安全的想法,但是: 在 shell 脚本中使用 passwd 命令