bash 脚本并行 ssh 远程命令
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26338438/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
bash script parallel ssh remote command
提问by Cyrus
i have a script that fires remote commands on several different machines through ssh connection. Script goes something like:
我有一个脚本,它通过 ssh 连接在几台不同的机器上触发远程命令。脚本类似于:
for server in list; do
echo "output from $server"
ssh to server execute some command
done
The problem with this is evidently the time, as it needs to establish ssh connection, fire command, wait for answer, print it. What i would like is to have script that would try to establish connections all at once and return echo "output from $server" and output of command as soon as it gets it, so not necessary in the list order.
这显然是时间问题,因为它需要建立 ssh 连接,启动命令,等待应答,打印它。我想要的是让脚本尝试一次建立所有连接,并在收到后立即返回 echo“来自 $server 的输出”和命令输出,因此在列表顺序中没有必要。
I've been googling this for a while but didn't find an answer. I cannot cancel ssh session after command run as one thread suggested, because i need an output and i cannot use parallel gnu suggested in other threads. Also i cannot use any other tool, i cannot bring/install anything on this machine, only useable tool is GNU bash, version 4.1.2(1)-release.
我已经在谷歌上搜索了一段时间,但没有找到答案。命令运行后我无法取消 ssh 会话,因为我需要一个输出,并且我不能使用其他线程中建议的并行 gnu。另外我不能使用任何其他工具,我不能在这台机器上带/安装任何东西,唯一可用的工具是 GNU bash,版本 4.1.2(1)-release。
Another question is how are ssh sessions like this limited? If i simply paste 5+ or so lines of "ssh connect, do some command" it actually doesn't do anything, or execute only on first from list. (it works if i paste 3-4 lines). Thank you
另一个问题是如何限制像这样的 ssh 会话?如果我只是粘贴 5 行以上的“ssh 连接,执行一些命令”,它实际上什么都不做,或者只在列表中的第一个上执行。(如果我粘贴 3-4 行,它会起作用)。谢谢
回答by Cyrus
Have you tried this?
你试过这个吗?
for server in list; do
ssh user@server "command" &
done
wait
echo finished
Update:Start subshells:
更新:启动子shell:
for server in list; do
(echo "output from $server"; ssh user@server "command"; echo End $server) &
done
wait
echo All subshells finished
回答by damienfrancois
There are several parallel SSH tools that can handle that for you:
有几个并行的 SSH 工具可以为您处理:
- http://code.google.com/p/pdsh/
- http://sourceforge.net/projects/clusterssh/
- http://code.google.com/p/sshpt/
- http://code.google.com/p/parallel-ssh/
- http://code.google.com/p/pdsh/
- http://sourceforge.net/projects/clusterssh/
- http://code.google.com/p/sshpt/
- http://code.google.com/p/parallel-ssh/
Also, you could be interested in configuration deployment solutions such as Chef, Puppet, Ansible, Fabric, etc (see this summary).
此外,您可能对配置部署解决方案感兴趣,例如 Chef、Puppet、Ansible、Fabric 等(请参阅此摘要)。
A third option is to use a terminal broadcast such as pconsole
第三种选择是使用终端广播,例如pconsole
If you only can use GNU commands, you can write your script like this:
如果您只能使用 GNU 命令,您可以像这样编写脚本:
for server in $servers ; do
( { echo "output from $server" ; ssh user@$server "command" ; } | \
sed -e "s/^/$server:/" ) &
done
wait
and then sort
the output to reconcile the lines.
然后sort
输出以协调行。
回答by zerodeux
I started with the shell hacks mentionned in this thread, then proceeded to something somewhat more robust : https://github.com/bearstech/pussh
我从本线程中提到的 shell hacks 开始,然后进行了一些更强大的操作:https: //github.com/bearstech/pussh
It's my daily workhorse, and I basically run anything against 250 servers in 20 seconds (it's actually rate limited otherwise the connection rate kills my ssh-agent). I've been using this for years.
这是我的日常工作,我基本上在 20 秒内针对 250 个服务器运行任何东西(它实际上是速率限制的,否则连接速率会杀死我的 ssh 代理)。我多年来一直在使用这个。
See for yourself from the man page (clone it and run 'man ./pussh.1') : https://github.com/bearstech/pussh/blob/master/pussh.1
:从该名男子页(克隆并运行“人./pussh.1”)见自己https://github.com/bearstech/pussh/blob/master/pussh.1
Examples
例子
Show all servers rootfs usage in descending order :
按降序显示所有服务器 rootfs 使用情况:
pussh -f servers df -h / |grep /dev |sort -rn -k5
Count the number of processors in a cluster :
计算集群中的处理器数量:
pussh -f servers grep ^processor /proc/cpuinfo |wc -l
Show the processor models, sorted by occurence :
显示处理器型号,按出现次数排序:
pussh -f servers sed -ne "s/^model name.*: //p" /proc/cpuinfo |sort |uniq -c
Fetch a list of installed package in one file per host :
在每个主机的一个文件中获取已安装软件包的列表:
pussh -f servers -o packages-for-%h dpkg --get-selections
Mass copy a file tree (broadcast) :
批量复制文件树(广播):
tar czf files.tar.gz ... && pussh -f servers -i files.tar.gz tar -xzC /to/dest
Mass copy several remote file trees (gather) :
批量复制几个远程文件树(收集):
pussh -f servers -o '|(mkdir -p %h && tar -xzC %h)' tar -czC /src/path .
Note that the pussh -ufeature (upload and execute) was the main reason why I programmed this, no tools seemed to be able to do this. I still wonder if that's the case today.
请注意,push -u功能(上传和执行)是我编程的主要原因,似乎没有工具能够做到这一点。我仍然想知道今天是否是这种情况。
回答by Dettorer
You may like the parallel-ssh projectwith the pssh
command:
您可能会喜欢带有以下命令的 parallel-ssh 项目pssh
:
pssh -h servers.txt -l user command
It will output one line per server when the command is successfully executed. With the -P
option you can also see the output of the command.
命令执行成功后,每台服务器输出一行。使用该-P
选项,您还可以查看命令的输出。