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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 11:32:42  来源:igfitidea点击:

bash script parallel ssh remote command

bashsshparallel-processing

提问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 工具可以为您处理:

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 sortthe 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 psshcommand:

您可能会喜欢带有以下命令的 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 -Poption you can also see the output of the command.

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