循环执行一系列 ssh 命令时出现的问题

循环执行一系列 ssh 命令时出现的问题

我有一系列服务器,我想在这些服务器上运行相同的命令。每个命令都要花几个小时,而且(即使我使用 nohup 运行命令并将它们设置为在后台运行)我必须等待每个命令完成后才能开始下一个命令。以下是我大致的设置方式:

在主机上:

for i in {1..9}; do ssh RemoteMachine${i} ./RunJobs.sh; done

其中每台远程机器上的 RunJobs.sh 为:

 source ~/.bash_profile
cd AriadneMatching
for file in FileDirectory/Input_*;
do
    nohup ./Executable ${file} &
done
exit

有谁知道有一种方法可以让我不必等待每项工作完成后再开始下一项工作?或者有更好的方法,我感觉我的做法不太理想。谢谢,杰克

答案1

本地机器的解决方案

基于并行-ssh

# pssh -P --par 2 --hosts RemoteMachines /opt/RunJobs.sh

或者:

# pssh -i --par 2 --hosts RemoteMachines /opt/RunJobs.sh

解释参数:

-P
--print
    Display output as it arrives.  This option is of limited usefulness
    because output from different hosts are interleaved.

-i
--inline
    Display standard output and standard error as each host completes.

-p parallelism
--par parallelism
    Use the given number as the maximum number of concurrent connections.

-h host_file
--hosts host_file
    Read hosts from the given host_file.

基于ansible

# ansible --forks 2 -i RemoteMachines '*' -m command -a /opt/RunJobs.sh

解释参数:

-f NUM, --forks=NUM
    Level of parallelism.  NUM is specified as an integer, the default is 5.

-i PATH, --inventory=PATH
    The PATH to the inventory hosts file, which defaults to /etc/ansible/hosts.

-m NAME, --module-name=NAME
    Execute the module called NAME.

-a 'ARGUMENTS', --args='ARGUMENTS'
    The ARGUMENTS to pass to the module.

命令module 采用命令名称,后跟空格分隔的参数列表。给定的命令将在所有选定节点上执行。它不会通过 shell 处理,因此 $HOME 等变量以及“<”、“>”、“|”和“&”等操作将不起作用。

您可以在临时命令简介

NB安塞波直到所有当前主机(“fork”)都完成之后,才会切换到下一组主机,因此其并行性较低密码(可能有办法可以增加它,但我不知道)。

远程机器对于这两种情况,文件看起来都是这样的:

[email protected]
[email protected]
[email protected]
[email protected]

远程机器的解决方案

改写运行作业变成这样:

find FileDirectory -name 'Input_*' -print0 | xargs -0 -P 2 -n 1 ./Executable

解释

-0, --null
       Input items are terminated by a null character instead of by
       whitespace, and the quotes and backslash are not special (every
       character is taken literally).  Disables the end of file string,
       which is treated like any other argument.  Useful when input items
       might contain white space, quote marks, or backslashes.  The GNU find
       -print0 option produces input suitable for this mode.

-P max-procs, --max-procs=max-procs
       Run  up to max-procs  processes at a time; the default is 1.  If
       max-procs is 0, xargs will run as many processes as possible at a
       time.  Use the -n option or the -L option with -P; otherwise chances
       are  that  only  one  exec will be done.

 -n max-args, --max-args=max-args
       Use at most max-args arguments per command line.  Fewer than
       max-args arguments will be used if the size (see the -s option) is
       exceeded, unless the -x option is given, in which case xargs will
       exit.

nitro2k01解决方案基于GNU 并行更强大,但正如你所见,GNU xargs也不错。

答案2

首先,您可能希望使用screen而不是 来nohup使会话在断开连接后继续存在。screen为您提供一个稍后可以返回的虚拟终端。基本用法是screen yourcommand执行yourcommandscreen -DR自动连接到现有会话,如果不存在则创建一个新会话。只需运行不带参数的 screen 也会在您可以使用的“屏幕”内为您提供提示。

其次,你可能需要研究GNU 并行对于并行作业。您可能不希望运行的进程多于 CPU 核心数,因为收益递减和磁盘过载。适合您的命令可能如下,同样,您必须在屏幕内运行它才能使其在断开连接后继续运行。

ls FileDirectory/Input_* | parallel -j 8 --workdir $PWD ./Executable {}

列出您要处理的文件并通过管道传输到其中parallel,指示运行 8 个并行作业并在当前目录中工作。

由于 screen 不理解作为参数给出的命令中的管道和其他内容 - 这是 shell 的工作 - 您需要将命令放在 shell 脚本中或给出 sh -c 命令来执行该命令。

screen sh -c 'ls FileDirectory/Input_* | parallel -j 8 --workdir $PWD ./Executable {}'

或者简单地

screen ./runjob

其中runjob包含:

#!/usr/bin/env bash
ls FileDirectory/Input_* | parallel -j 8 --workdir $PWD ./Executable {}

答案3

使用屏幕在每台机器上,screen 启动一个命令(通常是一个 shell),它可以与你的 ssh 会话分离,以便它继续执行刚刚在其中启动的作业;换句话说,虽然该作业仍在运行,但当你注销时,不会被任何中断(不仅仅是 kill -9)打断。

当你愿意时,你可以通过 ssh 重新连接,并通过以下命令重新加入分离的会话

screen -r

这样就可以无缝地让你回到你放弃的 shell,同时向你显示你在此期间错过的所有标准输出(如果有)。

这样,您就不必等待任何事情,也不会有危险的挂起的 ssh 会话,如果意外断开连接,会导致您的工作失败。

屏幕在存储库中。

答案4

对于 {1..9} 中的 i;执行 ssh RemoteMachine${i} ./RunJobs.sh;完成

尝试这个

for i in {1..9}; do echo RemoteMachine${i}; done |xargs -I % -n 1 -P 10 ssh
% "./RunJobs.sh"

它的作用是构建一个机器名称列表,并将整个列表通过管道传输到 xargs。xargs 的参数含义为:

-I % 用第一个参数替换出现的 %

-n 1 每个命令行使用 1 个参数

-P 10 一次运行10个进程

相关内容