【问题标题】:How can I execute parallel "for" loops in Bash?如何在 Bash 中执行并行“for”循环?
【发布时间】:2017-12-13 06:15:02
【问题描述】:

我一直在尝试并行化以下脚本,特别是 for 循环。我该怎么做?

#!/bin/bash
for i in `cat /root/vms`;
do
    /usr/bin/sshpass -p 'test' /usr/bin/ssh -o StrictHostKeyChecking=no \
        -l testuser $i -t 'echo test | sudo -S yum update -y'
done

【问题讨论】:

  • 如你所写:for loopS - 你想并行运行多个for 循环吗?在这种情况下,您应该指定循环数

标签: linux bash parallel-processing


【解决方案1】:

替换

/usr/bin/sshpass ...

/usr/bin/sshpass ... &

【讨论】:

  • 这里的事情是for循环正在串行执行。我想并行执行for循环。
  • 这就是此更改的作用。如果您的文件 /root/vms 包含 20 行,这将启动 20 个 sshpass 并行。
  • @gosatriani,你是如何实现你的“串行执行”的?从技术上讲,这种方法将每个命令作为后台作业启动,并行运行
【解决方案2】:

您可以使用 GNU Parallel 非常简洁地做到这一点,如下所示:

parallel -a /root/vms /usr/bin/sshpass -p \'test\' /usr/bin/ssh -o StrictHostKeyChecking=no -l testuser {} -t \'echo test \| sudo -S yum update -y\'

所以,如果您的 /root/vms 包含:

vm-ubuntuLTS
vm-centos
vm-debian
vm-arch

然后您添加 --dry-run 选项以查看它会做什么,而无需实际执行任何操作:

parallel --dry-run -a /root/vms /usr/bin/sshpass -p \'test\' /usr/bin/ssh -o StrictHostKeyChecking=no -l testuser {} -t \'echo test \| sudo -S yum update -y\'

样本输出

/usr/bin/sshpass -p 'test' /usr/bin/ssh -o StrictHostKeyChecking=no -l testuser vm-debian -t 'echo test | sudo -S yum update -y'
/usr/bin/sshpass -p 'test' /usr/bin/ssh -o StrictHostKeyChecking=no -l testuser vm-centos -t 'echo test | sudo -S yum update -y'
/usr/bin/sshpass -p 'test' /usr/bin/ssh -o StrictHostKeyChecking=no -l testuser vm-ubuntuLTS -t 'echo test | sudo -S yum update -y'
/usr/bin/sshpass -p 'test' /usr/bin/ssh -o StrictHostKeyChecking=no -l testuser vm-arch -t 'echo test | sudo -S yum update -y'

与其重复所有ssh 选项,不如考虑将它们放入$HOME/.ssh/config 的文件中,如下所示:

Host vm-centos
HostName vm-centos
User freddy
   StrictHostKeyChecking no

Host vm-arch
HostName vm-arch
   User frog
   Port 2222
   ServerAliveInterval 10

【讨论】:

  • 当我使用上述命令时,同时出现一些语法错误:警告:您正在使用--tollef。如果事情很奇怪,请使用--gnu。并行:警告:--tollef 已过时,将停用 20140222。并行:警告:请参阅:lists.gnu.org/archive/html/parallel/2013-02/msg00018.html /usr/bin/sshpass:vm-centos:找不到命令 -p:vm-centos:找不到命令 'test ': vm-centos: 找不到命令 /usr/bin/ssh: vm-centos: 找不到命令 -o: vm-centos: 找不到命令
  • 这意味着您的发行版发布了旧版本的 GNU Parallel。要么更新它,要么只使用 parallel --gnu <OTHER OPTIONS> 你的版本是 2014 年的。
【解决方案3】:

GNU Parallel 有一个 --nonall 选项和一个环境变量来设置要使用的 ssh-command:

PARALLEL_SSH="/usr/bin/sshpass -p test /usr/bin/ssh -o StrictHostKeyChecking=no -l testuser -t"
export PARALLEL_SSH
parallel --slf /root/vms --nonall 'echo test | sudo -S yum update -y'

如果您要运行的东西有点复杂,您可以创建一个函数并让 GNU Parallel 传输:

complex_task() {
  # Do complex task
  echo test | sudo -S yum update -y
  # and a lot more complex stuff
}
export -f complex_task
PARALLEL_SSH="/usr/bin/sshpass -p test /usr/bin/ssh -o StrictHostKeyChecking=no -l testuser -t"
export PARALLEL_SSH
parallel --slf /root/vms --env complex_task --nonall complex_task

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多