Bash:如何在不通过 SSH 回显的情况下从标准输入读取密码
Bash: How to read password from stdin without echoing over SSH
我有以下有效的脚本:
echo -n "Enter sudo password: "
read -s sudo_pass
echo "$sudo_pass" | ssh -tt myhost "sudo -S ./remote_script.sh"
问题出在输出上。我希望 stdin
的密码供 sudo
使用,但不要打印到屏幕上。相反,我得到:
<system banner>
thepassw0rd
[sudo] password for theuser:
有没有办法做到这一点?我什至不确定哪个命令导致输入被打印出来。
更新
我发现 ssh 正在打印输入:
echo 123 | ssh -tt myhost "sleep 2"
这给了我
<system banner>
123
Connection to myhost closed.
这里的问题在于 ssh
的 -tt
选项。你强迫它分配一个伪终端。这个伪终端读取标准输入,但不知道它读取的内容是来自您的键盘还是重定向 (echo "$sudo_pass" | ssh ...
)。所以它就像一个终端并回显它接收到的内容(因为它在 sudo
有时间 运行 并捕获标准输入之前接收到它)。
您遇到了 -t
选项的缺点之一。另一个还没有打到你的是,如果你的密码以 ssh
转义序列(~C
、~?
等)开头,这也不会按预期工作。
简单且最佳的解决方案:不要使用 -tt
选项。
如果你真的离不开它 - 因为例如你的远程脚本坚决想要一个终端 - 一个(丑陋的)解决方案是“吃掉”ssh
发回的第一行,因为你肯定知道回显的永远是你的密码:
echo "$sudo_pass" | ssh -tt myhost ... | ( read; cat )
就个人而言,我不太确定第一行总是密码,我不推荐这样做。一个更好的选择是在发送密码之前添加一个小延迟,以便让 sudo
远程启动并捕获标准输入:
( sleep 1; echo "$sudo_pass" ) | ssh -tt myhost ...
但这仍然是一个 hack,最好的解决方案当然是不使用 ssh
的 -tt
选项。
我有以下有效的脚本:
echo -n "Enter sudo password: "
read -s sudo_pass
echo "$sudo_pass" | ssh -tt myhost "sudo -S ./remote_script.sh"
问题出在输出上。我希望 stdin
的密码供 sudo
使用,但不要打印到屏幕上。相反,我得到:
<system banner>
thepassw0rd
[sudo] password for theuser:
有没有办法做到这一点?我什至不确定哪个命令导致输入被打印出来。
更新
我发现 ssh 正在打印输入:
echo 123 | ssh -tt myhost "sleep 2"
这给了我
<system banner>
123
Connection to myhost closed.
这里的问题在于 ssh
的 -tt
选项。你强迫它分配一个伪终端。这个伪终端读取标准输入,但不知道它读取的内容是来自您的键盘还是重定向 (echo "$sudo_pass" | ssh ...
)。所以它就像一个终端并回显它接收到的内容(因为它在 sudo
有时间 运行 并捕获标准输入之前接收到它)。
您遇到了 -t
选项的缺点之一。另一个还没有打到你的是,如果你的密码以 ssh
转义序列(~C
、~?
等)开头,这也不会按预期工作。
简单且最佳的解决方案:不要使用 -tt
选项。
如果你真的离不开它 - 因为例如你的远程脚本坚决想要一个终端 - 一个(丑陋的)解决方案是“吃掉”ssh
发回的第一行,因为你肯定知道回显的永远是你的密码:
echo "$sudo_pass" | ssh -tt myhost ... | ( read; cat )
就个人而言,我不太确定第一行总是密码,我不推荐这样做。一个更好的选择是在发送密码之前添加一个小延迟,以便让 sudo
远程启动并捕获标准输入:
( sleep 1; echo "$sudo_pass" ) | ssh -tt myhost ...
但这仍然是一个 hack,最好的解决方案当然是不使用 ssh
的 -tt
选项。