我正在寻找一种将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
干杯!
有几种方法可以做到这一点。
ssh user@remote_server 'bash -s' < localfile
cat localfile | ssh user@remote_server
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)。 一些工作可能需要正确传递错误/返回代码从远程命令….