我试图通过ssh解压多个tar文件:
ssh user@hostname "cat /dir/file*.tgz" | tar xvzf -
以上仅适用于远程服务器上的第一个文件匹配。本地(dest)服务器只接收一个文件。已验证通配符匹配多个文件。
还有其他办法吗?
答案 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 -)
答案 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仍然是必要的。 子>