如何通过ssh解压缩多个tar文件?

时间:2011-06-01 23:33:55

标签: bash ssh tar

我试图通过ssh解压多个tar文件:

ssh user@hostname "cat /dir/file*.tgz" | tar xvzf -

以上仅适用于远程服务器上的第一个文件匹配。本地(dest)服务器只接收一个文件。已验证通配符匹配多个文件。

还有其他办法吗?

5 个答案:

答案 0 :(得分:4)

(首次尝试后编辑无效:)

另一个想法,避免多个ssh调用以及scp(因为这需要每个文件之间至少有一次往返):

ssh user@hostname 'tar cf - /dir/file*.tgz' | tar xf - --to-command='tar xzvf -'

我们在服务器端使用一个tar调用将所有文件包装在一起,在客户端再调用tar来再次打开它们,然后调用{{1}每个条目一次。这与 sehe 中的base64-answer类似,但效率更高,因为它不会炸毁文件。

答案 1 :(得分:2)

mkdir /tmp/tars
scp 'user@hostname:/dir/file*.tgz' /tmp/tars/
foreach tarname in /tmp/tars/*.tgz; do tar xzvf "$tarname"; done

如果您绝对无法存储临时副本:

ssh user@hostname 'ls /dir/file*.tgz' | while read tarname; 
do
    ssh user@hostname "cat '/dir/$tarname'" | tar xzvf -
done

答案 2 :(得分:1)

您可以将其包装在find调用中,然后使用exec开关迭代每个找到的文件。

ssh user@hostname 'find /path/to/dir -name "*.tar.gz" -exec tar xvf "{}" ";"'

单个ssh调用,无需编写bash脚本。

答案 3 :(得分:0)

CarpeNoctem激励我走得更远,提供一站式解决方案,只需要一个ssh连接,并完成所有流媒体。

经过测试的证明概念(为了可读性而格式化的oneline):

 (echo '#!/bin/sh'; 
  for a in /dir/file*.tgz
  do 
      echo 'base64 -d <<"TARIMAGE" | tar xvzf -'
      base64 "$a"
      echo "TARIMAGE"
  done) | ssh -C remote 'cd /targetdir && sh -'

当然,您实际上想要反转本地和远程的角色,在这种情况下,我建议将脚本生成转换为shell脚本:

gen_script.sh,chmod + x

#!/bin/bash
echo '#!/bin/sh'; 
for a in /dir/file*.tgz
do 
    echo 'base64 -d <<"TARIMAGE" | tar xvzf -'
    base64 "$a"
    echo "TARIMAGE"
done

调用

scp gen_script.sh user@hostname:
ssh -C user@hostname /home/user/gen_script.sh | (cd targetdir && sh -)

松散的结局,想法:

  • 你可以用uuencode,od,xxd,pgp或whatnot代替base64
  • 您可以在ssh(ssh -C)上启用压缩以进一步优化带宽
  • 我做了targetdir / step up以防止意外;如果你不需要它,你可以放手:)

答案 4 :(得分:0)

使用文件比使用命令更容易。因此,不是使用ssh命令来访问远程主机,而是使用tar命令来访问存档,而是使用SSHFS文件系统来访问远程主机上的文件

mkdir hostname-dir.tmp
sshfs user@hostname:/dir hostname-dir.tmp
for a in hostname-dir.tmp/*.tgz; do tar xvf "$a"; done
fusermount -u hostname-dir.tmp

您甚至可以更进一步,AVFS访问档案作为目录¹。所有这些都由FUSE带给您,这是一个通用框架,可以将各种事物作为文件进行访问。

mountavfs
mkdir hostname-dir.tmp
sshfs user@hostname:/dir hostname-dir.tmp
for a in ~/.avfs$PWD/hostname-dir.tmp/*.tgz; do cp -Rp "$a#"/* .; done
fusermount -u hostname-dir.tmp

如果您的shell是zsh,则for循环可以替换为glob qualifier

cp -Rp ~/.avfs$PWD/hostname-dir.tmp/*.tgz(e\''reply=($REPLY\#/*)'\') .

¹ AVFS也可以通过SSH访问远程文件,但我认为您不能以这种方式访问​​远程存档:AVFS路径只有一个跃点。所以SSHFS仍然是必要的。