输送SSH Sudo的输出



我有时需要在远程服务器上运行命令,并在本地服务器上解析命令的输出。远程服务器不允许使用ssh的根登录,但是具有需要密码的方式配置的sudo。我需要做的简单示例是

ssh remote sudo echo bar | tr bar foo

(显然,在这个简化的示例中,没有充分的理由需要在另一台机器上运行echotr:这只是一个玩具示例来解释我要做的事情。(

如果我在上面运行命令,我会发现sudo无法提示密码的错误:

richard@local:~$ ssh remote sudo echo bar | tr bar foo
sudo: no tty present and no askpass program specified

我可以尝试解决此问题的一种方法是将-t选项添加到ssh。如果我这样做,sudo确实会等待并接受密码,但是ssh的伪终端的输出将转到Stdout,这意味着Sudo提示消息将管道输送到tr,并且未向用户显示。如果用户不知道sudo正在等待密码,他们会认为脚本已悬挂,并将快速消息传递给管道可能会破坏进一步的处理:

richard@local:~$ ssh -t remote sudo echo bar | tr bar foo
[sudo] posswood foo oichood: 
foo

(当然,这个愚蠢的示例表明该提示已通过tr命令处理。

我可以看到的另一种方法是通过将-S选项添加到sudo中。如果我这样做,则sudo在STDERR上提示以获取密码,因此该提示不会从管道下传递。很好,但是sudo也接受标准输入的密码,这意味着它已回应到终端,任何人看着用户的肩膀都可以阅读:

richard@local:~$ ssh remote sudo -S echo bar | tr bar foo
[sudo] password for richard: p8ssw0rd
foo

我发现了这两个选项解决问题的不高度方式,但是如果用户第一次错误地弄错了密码,我的解决方法就遇到了问题。这本身就是一个问题。例如:

richard@local:~$ echo "[sudo] password for $USER:"; 
  ssh -t remote sudo echo bar | tail +2 | tr bar foo
richard@local:~$ (read -s password; echo $password; echo >&2) 
  | ssh remote sudo -S echo bar | tr bar foo

我确定这必须有一个很好的解决方案,因为这似乎并不罕见。有什么想法吗?

我想出的最好的解决方案是使用 sudo -S并禁用本地回声,因此在输入它时未显示密码:

$ { stty -echo; ssh remote sudo -S echo hello; stty echo; echo 1>&2; }
[sudo] password for user:
hello

这会使Sudo负责密码提示,因此如果用户键入错误的密码,则可以正常工作。

我认为使用ssh -t的任何解决方案都无法正常工作,因为它结合了stderr和Stdout。

相关内容

  • 没有找到相关文章

最新更新