如何在Bash中执行并行“for”循环?

时间:2017-12-13 06:15:03

标签: linux bash parallel-processing

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

import java.lang.*;
import java.lang.Thread;
import java.lang.Runnable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReentrantLock;

class Numprintt implements Runnable {
    private final CountDownLatch latch;
    private String myName;

    public Numprintt(String name, CountDownLatch latch) {
        this.myName = name;
        this.latch = latch;
    }

    public void run() {
        for (int i = 0; i < 10; i++) {
            if (i == 9 && latch != null) {
                try {
                    latch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            System.out.print(myName + i + " ");
        }
    }
}


public class MyRunnableTest {

    public static void main(String[] ar) {

        CountDownLatch latch = new CountDownLatch(1);

        Numprintt A = new Numprintt("A", null);
        Numprintt B = new Numprintt("B", latch);


        Thread t1 = new Thread(A);
        Thread t2 = new Thread(B);

        t1.start();
        t2.start();

        try {
            t1.join();
            latch.countDown();
            t2.join();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3 个答案:

答案 0 :(得分:3)

替换

/usr/bin/sshpass ...

/usr/bin/sshpass ... &

答案 1 :(得分: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

答案 2 :(得分:0)

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

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