bash脚本并行ssh远程命令

时间:2014-10-13 11:01:23

标签: bash ssh parallel-processing

我有一个脚本,通过ssh连接在几台不同的机器上触发远程命令。脚本类似于:

for server in list; do
echo "output from $server"
ssh to server execute some command
done

这个问题显然是时间,因为它需要建立ssh连接,fire命令,等待答案,打印它。我想要的是让脚本尝试一次建立连接并返回来自$ server"的echo"输出命令输出后立即输出,所以在列表顺序中没有必要。

我已经谷歌搜索了一段时间,但没有找到答案。我不能在命令运行后取消ssh会话作为一个线程建议,因为我需要一个输出,我不能使用其他线程中建议的并行gnu。另外我不能使用任何其他工具,我不能在这台机器上带任何东西,只有可用的工具是GNU bash,版本4.1.2(1) - 发布。

另一个问题是这样的ssh会话有限吗?如果我只是粘贴5个左右的" ssh连接线,请执行一些命令"它实际上没有做任何事情,或者只在列表中首先执行。 (如果我粘贴3-4行就可以了)。谢谢

4 个答案:

答案 0 :(得分:8)

你试过这个吗?

for server in list; do
  ssh user@server "command" &
done
wait
echo finished

更新:启动子广告:

for server in list; do
  (echo "output from $server"; ssh user@server "command"; echo End $server) &
done
wait
echo All subshells finished

答案 1 :(得分:3)

有几种并行的SSH工具可以为您处理:

此外,您可能对配置部署解决方案感兴趣,例如Chef,Puppet,Ansible,Fabric等(请参阅this summary)。

第三种选择是使用终端广播,例如pconsole

如果您只能使用GNU命令,则可以像这样编写脚本:

for server in $servers ; do
   ( { echo "output from $server" ; ssh user@$server "command" ; } | \
    sed -e "s/^/$server:/" ) & 
done
wait 

然后sort输出以协调这些行。

答案 2 :(得分:3)

我从这个帖子中提到的shell hacks开始,然后进行了一些更健壮的东西:https://github.com/bearstech/pussh

这是我的日常工作,我基本上在20秒内对250台服务器运行任何东西(它实际上是速率限制的,否则连接速率会杀死我的ssh-agent)。我多年来一直在使用它。

从手册页中查看(克隆并运行'man ./pussh.1'):https://github.com/bearstech/pussh/blob/master/pussh.1

<强>实施例

按降序显示所有服务器rootfs用法:

pussh -f servers df -h / |grep /dev |sort -rn -k5

计算群集中的处理器数量:

pussh -f servers grep ^processor /proc/cpuinfo |wc -l

显示按出现次数排序的处理器型号:

pussh -f servers sed -ne "s/^model name.*: //p" /proc/cpuinfo |sort |uniq -c

在每个主机的一个文件中获取已安装软件包的列表:

pussh -f servers -o packages-for-%h dpkg --get-selections

批量复制文件树(广播):

tar czf files.tar.gz ... && pussh -f servers -i files.tar.gz tar -xzC /to/dest

批量复制多个远程文件树(聚集):

pussh -f servers -o '|(mkdir -p %h && tar -xzC %h)' tar -czC /src/path .

请注意, pussh -u 功能(上传和执行)是我编程的主要原因,似乎没有工具可以做到这一点。我仍然想知道今天情况是否如此。

答案 3 :(得分:1)

您可能希望the parallel-ssh project使用pssh命令:

pssh -h servers.txt -l user command

成功执行命令后,每个服务器将输出一行。使用-P选项,您还可以看到命令的输出。