前言

在一台linux主机上执行命令,如果太繁琐可以写成 Shell 脚本;如果在一个集群上批量执行命令呢?
一台一台的ssh登录去执行当然是可以的,如果集群太大,就太繁琐了。下面介绍一些在集群上执行命令的方法。

ssh 远程执行命令

通过 ssh 可以按照下面的方式远程执行命令
1
ssh user@host 'command1;command2;command3'

或者使用管道

1
ssh user@host 'command1|command2|command3'

或者使用如下的

1
2
3
4
5
$ ssh [user]@[server] << EOF
command 1
command 2
command 3
EOF

或者将要执行的命令写入 Shell 脚本

1
$ ssh user@host 'bash -s' < local_script.sh

可以通过指定ssh 参数 -o StrictHostKeyChecking=no 来省去下面的交互过程

但是上面的方法执行 sudo 命令的时候会出错
此时需要加上 ssh 的 -t 参数
man 一下 ssh 查找 -t 参数可以看到如下的解释

-t
Force pseudo-tty allocation. This can be used to execute arbi‐
trary screen-based programs on a remote machine, which can be
very useful, e.g. when implementing menu services. Multiple -t
options force tty allocation, even if ssh has no local tty.

具体的意思就是强制提供一个远程服务器的虚拟tty终端

1
ssh -t -p port user@host 'cmd'

即可执行sudo命令,但是自己还要手工输入远程服务器的密码

要想写在脚本中自动执行还需要使用 expect
expect是 linux下的一个命令用来处理执行命令中的交互,python 也有相应的库 pexpect

Expect is a program that “talks” to other interactive programs accord‐
ing to a script.

下面是参考的一些文章

Send Remote Commands Via SSH
Running Commands on a Remote Linux Server over SSH

其他集群管理命令

如 pssh mussh

linux集群管理工具mussh和pssh

fabric

fabric 是基于 ssh 的一个python库,主要用来做运维或者批量部署
fabric官网

  • 安装 fabric
    1
    pip install fabric

安装完成即可使用 fabric,fabric上手简单,功能强大

1
fab -f xxx.py command

fab 默认在当前目录下寻找 fabfiles,如果你的文件是其他的名字,使用 -f指定即可

脚本的编写

1
2
3
4
from fabric.api import run

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

运行

1
2
3
4
5
6
7
8
9
$ 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.

使用 -H可以指定运行的host, 也可以在代码中指定。
用户名和密码都是存在 env 环境变量中,也可在脚本中更改
The environment dictionary

同时 fabric 还提供了一些装饰器,具体的可以查文档

1
2
3
4
@parralel
@task
@role()
@host()

详细讲解可以参考这篇文章 Python fabric实现远程操作和部署