tar -z文件一次到多个服务器?

时间:2015-03-05 23:20:07

标签: bash shell unix

什么是将同一文件一次压缩和tar到多个服务器的更有效方法?现在我有:

for SERVER in $SERVERS; do
  tar czpf - my/directory | ssh $SERVER tar xzpf - &
done && wait

它完成了工作,并行运行循环是一种改进,但是有大约20台服务器在我的终端上进行了大量的冗余压缩。有没有办法只计算一次tarball,然后将相同的输出复制到循环中的每个ssh命令中?

2 个答案:

答案 0 :(得分:3)

这不会是DRY,但是流程替换和tee可以做到:

tar czpf - my/directory | tee \
    >(ssh server1 tar xzpf -) \
    >(ssh server2 tar xzpf -) \
    >(ssh server3 tar xzpf -) \
    >(ssh server4 tar xzpf -) \
    ...                       \
    >(ssh server20 tar xzpf -) \
    >/dev/null

最后重定向到/dev/null会阻止在终端上打印存档内容。

...

我看到这只是glglgl的#1点明确说明。制作答案社区维基

答案 1 :(得分:2)

您可以使用tee执行某项操作,并使用FIFO或(在更高级的shell上,例如bash)使用>(command)构造。

这可能有两种可能的方式:

  1. 您可以在循环中构建命令行,以便以tee >(ssh host1 tar xzpf -) >(ssh host2 tar xzpf -)之类的命令结束。如何在Bash中这样做对我来说并不完全清楚;要么你可以使用数组,但我不确定,或者你必须使用eval
  2. 您可以从一个名为FIFO的“初始”开始,其中tar数据通过管道输入。然后,在每次迭代中,您mkfifo next_pipe; tee <previous_pipe >(ssh ...) > next_pipe在每次迭代中创建一个命名FIFO。最后,为了启动while,complidated管道,您必须cat/dev/null的最后一个管道。

    这样的东西
    mkfifo 0
    tar czpf - my/directory > 0
    i=0
    for SERVER in $SERVERS; do
        i=$((i+1))
        mkfifo $i
        tee <$((i-1)) >(ssh $SERVER tar xzpf) >$i &
    end
    
  3. 然后等待所有进程完成。然后清理你的目录!

    那说我个人可能会编写一个Python脚本,它可以完成所有tee内容,并通过管道工作,而不是通过命名的FIFO。除其他外,最终可以从痛苦中解脱出来。

    如果这不是一个选项,使用本地中间文件对我来说似乎是最好的解决方案。

    但如果是的话,这是第一次完成这项工作的Python程序。这是一个完全未经测试的临时镜头,但显示了这个想法。

    #/usr/bin/env python
    import sys
    import subprocess
    cmd1 = sys.argv[1]
    cmd2 = sys.argv[2]
    hosts = sys.argv[3:]
    sp1 = subprocess.Popen(cmd1, shell=True, stdout=subprocess.PIPE)
    spn = []
    for host in hosts:
        sp = subprocess.Popen(['ssh', host, cmd1], stdin=subprocess.PIPE)
        spn.append(sp)
    while True:
        block = sp1.stdout.read(4096)
        if not block: break
        for sp in spn:
            sp.stdin.write(block)
    c = sp1.wait()
    for sp in spn:
        c2 = sp.wait()
        if not c: c = c2
    sys.exit(c)
    

    可以用

    调用
    ./program 'tar czpf - my/directory -' 'tar xzpf' host1 host2 host3 ...
    
相关问题