Bash:如何从stdin读取密码而不通过SSH回音

Bash:如何从stdin读取密码而不通过SSH回音,bash,ssh,sudo,Bash,Ssh,Sudo,我有以下脚本,它可以工作: 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] passw

我有以下脚本,它可以工作:

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:
这给了我

<system banner>

123
Connection to myhost closed.

123
与myhost的连接已关闭。

这里的问题在于
-tt
ssh
的选项。您正在强制它分配一个伪终端。这个伪终端读取stdin,不知道它读取的内容是来自键盘还是重定向(
echo“$sudo\u pass”| ssh…
)。因此,它就像一个终端,并回显它接收到的内容(因为它在
sudo
有时间运行和捕获stdin之前接收到它)

您遇到了
-t
选项的一个缺点。另一个尚未击中您的问题是,如果您的密码以
ssh
转义序列(
~C
~?
等)开头,这也不会像预期的那样工作

简单且最佳的解决方案:不要使用
-tt
选项

如果您真的不能没有它-例如,您的远程脚本坚决想要一个终端-一个(丑陋的)解决方案将是“吃掉”ssh发回的第一行,因为您肯定知道,它将始终是您的密码回显:

echo "$sudo_pass" | ssh -tt myhost ... | ( read; cat )
就个人而言,我不太确定第一行是否总是密码,我不建议这样做。一个更好的选择是在发送密码之前增加一点延迟,以便让
sudo
远程启动并捕获stdin:

( sleep 1; echo "$sudo_pass" ) | ssh -tt myhost ...

但是这仍然是一个黑客攻击,最好的解决方案当然是不要使用
ssh
“的
-tt
选项。为了简洁起见,这个脚本被显著地简化了。最后一行实际上是许多具有相同SUDO密码的服务器上的循环的一部分,我只想提示我的用户一次。您应该考虑配置<代码> SUDO 允许适当的用户在没有密码的情况下运行命令。您使用<代码> -TT<代码>,因为<代码> ReleTyScript。S/<代码>需要假操作,或者是因为你认为sudo是吗?如果我在这一点上完全诚实的话,我会说,“因为互联网是这么说的。”就在我看到你的评论之前,我尝试了
-T
,结果成功了。谢谢
-T
可能不是必需的;这是默认设置,可能用于覆盖(例如)SSH配置文件中的设置。值得注意的是,
sudo
-s
标志仍然是必需的,而
SSH
-tt
标志应该被删除。这绝对是@Shane,这是一个通用的答案。正如OP在他的问题中所展示的,这个问题独立于sudo。顺便说一句,谢谢你的编辑。
( sleep 1; echo "$sudo_pass" ) | ssh -tt myhost ...