如何通过SSH在远程机器上运行本地bash脚本?

我正在寻找一种将configuration从一台中央机器推送到多台远程机器的方法,而无需在远程机器上安装任何东西。

目标是做像你会发现像cfengine这样的工具,但在一套没有设置代理的机器上。 这实际上可能是在一组现有的远程机器上设置cfagent的好技术。

你可以传递一个脚本,并通过pipe道执行一个shell来暂时执行脚本。

例如

 echo "ls -l; echo 'Hello World'" | ssh me@myserver /bin/bash 

当然, "ls -l; echo 'Hello World'"部分可以用保存在本地机器上的bash脚本代替。

例如

 cat script.sh | ssh me@myserver /bin/bash 

干杯!

有几种方法可以做到这一点。

1:

 ssh user@remote_server 'bash -s' < localfile 

2:

 cat localfile | ssh user@remote_server 

3:

 ssh user@remote_server "$(< localfile)" 

数字3是我的首选方式,它允许交互式命令,例如su -S service nginx restart

(当使用su -S时,#1会将脚本的其余部分用作密码问题的input。)

我会为此推荐python的Fabric:

 #!/usr/bin/python # ~/fabfile.py from fabric_api import * env.hosts = ['host1', 'host2'] def deploy_script(): put('your_script.sh', 'your_script.sh', mode=0755) sudo('./your_script.sh') # from shell $ fab deploy_script 

你应该可以使用上面的开始。 请参阅Fabric的优秀文档来完成其余的工作。 作为附录,完全可以将脚本完全写入Fabric中 – 不需要复制,但是应该注意,要在所有机器上更改脚本,只需编辑本地副本并重新部署即可。 而且,除了API的基本用法之外,还可以根据当前运行的主机和/或其他variables来修改脚本。 这是一种pythonic期待。

这正是Ansible所使用的。 没有代理,你只需要创build一个名为:

 /etc/ansible/hosts 

其内容如下所示:

 [webhosts] web[1-8] 

这将指定机器“web1,web2 … web8”在组“webhosts”中。 然后你可以做这样的事情:

 ansible webhosts -m service -a "name=apache2 state=restarted" --sudo 

使用sudo在所有机器上重新启动apache2服务。

你可以在飞行命令,如:

 ansible webhosts -m shell -a "df -h" 

或者您可以在远程计算机上运行本地脚本:

 ansible webhosts -m script -a "./script.sh" 

或者您可以创build一个剧本(请查阅文档以获取详细信息),并提供您希望服务器符合的完整configuration并将其部署到:

 ansible-playbook webplaybook.yml 

基本上,你可以开始使用它作为命令行工具,在多台服务器上运行命令,并将其用法扩展到一个完整的configuration工具,你认为合适的。

正如在这个答案中解释的,你可以使用heredoc :

 ssh user@host <<'ENDSSH' #commands to run on remote host ENDSSH 

你必须小心heredoc,因为它只是发送文本,但它并不真的等待响应。 这意味着它不会等待你的命令被执行。

为什么不直接复制脚本,然后运行它呢?

 scp your_script.sh the_server: ssh the_server "chmod +x your_script.sh; ./your_script.sh" 

当然,你应该小心,不要把它上传到一个世界可写的地方,所以没有人可以摆弄它,然后再运行它(可能以root身份)。

重写脚本的方式是,其中的每个命令都已经以ssh作为前缀,而主机名/ ip或者这样的列表作为parameter passing给脚本(假设您设置了passwordless / ssh-agent密钥身份validation)。 一些工作可能需要正确传递错误/返回代码从远程命令….