通过SSH调用交互式Bash脚本

5
我正在编写一个“工具”——一些bash脚本,用于自动安装和配置集群中每个服务器。该“工具”从主服务器运行。它通过SCP将自身打包并分发到每个其他服务器,并通过“批量”SSH解压复制品。
在设置期间,该工具从主服务器发出远程命令,例如:echo './run_audit.sh' | ssh host4 'bash -s'。这种方法在许多情况下都有效,但当存在交互行为时,由于标准输入已经被使用,因此会出现问题。
有没有一种方法可以通过SSH交互式地运行远程bash脚本?
作为起点,请考虑以下情况:echo 'read -p "enter name:" name; echo "your name is $name"' | ssh host4 'bash -s'
在上述情况下,提示永远不会出现,我该如何解决?
提前致谢。

4
看看 Puppet 或类似的配置管理工具。不要通过交互式方式进行分布式配置。 - Dennis Williamson
3个回答

9

直接运行命令,如下:

ssh -t host4 bash ./run_audit.sh

为了再次演示,修改Shell脚本以从命令行或配置文件中读取选项,而不是从stdin(或优先于stdin)中读取。

我赞同Dennis Williamson的建议,应该考虑使用Puppet / etc。


起初我没有意识到,但这个方法很有效!使用无密码身份验证(DSA),我将脚本SCP到所有服务器并在远程执行它们。这个解决方案既分布式又交互式,正如我最初想要的那样。我只是根据Dennis的评论引入了配置来替换提示,但这不是重点。 - Mario Aguilera

1
听起来你可能想查一下expect

1
作为解决眼前问题的权宜之计,是的。正确的解决方法是不要需要交互式配置。 - tripleee
当然可以 - 但这并不总是一种可行的选择(在这种情况下,它是一个批处理脚本,但在更一般的情况下,可能是一个不容易修改的不同可执行文件)。 - Amber

0

不要通过stdin管道将命令传输到ssh,而是将shell脚本复制到远程机器:

scp ./run_audit.sh host4:

然后:

ssh host4 run_audit.sh

对于集群部署,我使用Fabric...它在SSH协议之上运行,无需守护程序。编写fabfile.py就像轻松简单的事情:
from fabric.api import run

def host_type():
    run('uname -s')

然后:

$ fab -H localhost,linuxbox host_type
[localhost] run: uname -s
[localhost] out: Darwin
[linuxbox] run: uname -s
[linuxbox] out: Linux

Done.
Disconnecting from localhost... done.
Disconnecting from linuxbox... done.

当然它可以做更多的事情...包括交互式命令,并且依赖于~/.ssh目录文件进行SSH。更多信息请参见fabfile.org。毫无疑问,你会因为这样的任务而忘记bash。;-)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接