fog*_*gus 10 bash scripting tar
我在同事的Bash脚本中看到了tar的以下有趣用法:
`tar cf - * | (cd <dest> ; tar xf - )`
Run Code Online (Sandbox Code Playgroud)
显然它的工作方式与rsync -av相似,但速度更快.问题出现了,怎么样?
-m
编辑:任何人都可以解释为什么这个解决方案优于以下?
cp -rfp * dest
Run Code Online (Sandbox Code Playgroud)
前者更快吗?
tva*_*son 12
它将存档写入标准输出,然后将其传送到子进程(由括号括起),该子进程将更改为其他目录并从标准输入读取/提取.这就是f论证后的破折号字符的含义.它基本上将当前目录的所有可见文件和子目录复制到另一个目录.
关于复制目录层次结构的cp和tar之间的区别,可以进行一个简单的实验来显示差异:
alastair box:~/hack/cptest [1134]% mkdir src
alastair box:~/hack/cptest [1135]% cd src
alastair box:~/hack/cptest/src [1136]% touch foo
alastair box:~/hack/cptest/src [1137]% ln -s foo foo-s
alastair box:~/hack/cptest/src [1138]% ln foo foo-h
alastair box:~/hack/cptest/src [1139]% ls -a
total 0
-rw-r--r-- 2 alastair alastair 0 Nov 25 14:59 foo
-rw-r--r-- 2 alastair alastair 0 Nov 25 14:59 foo-h
lrwxrwxrwx 1 alastair alastair 3 Nov 25 14:59 foo-s -> foo
alastair box:~/hack/cptest/src [1142]% mkdir ../cpdest
alastair box:~/hack/cptest/src [1143]% cp -rfp * ../cpdest
alastair box:~/hack/cptest/src [1144]% mkdir ../tardest
alastair box:~/hack/cptest/src [1145]% tar cf - * | (cd ../tardest ; tar xf - )
alastair box:~/hack/cptest/src [1146]% cd ..
alastair box:~/hack/cptest [1147]% ls -l cpdest
total 0
-rw-r--r-- 1 alastair alastair 0 Nov 25 14:59 foo
-rw-r--r-- 1 alastair alastair 0 Nov 25 14:59 foo-h
lrwxrwxrwx 1 alastair alastair 3 Nov 25 15:00 foo-s -> foo
alastair box:~/hack/cptest [1148]% ls -l tardest
total 0
-rw-r--r-- 2 alastair alastair 0 Nov 25 14:59 foo
-rw-r--r-- 2 alastair alastair 0 Nov 25 14:59 foo-h
lrwxrwxrwx 1 alastair alastair 3 Nov 25 15:00 foo-s -> foo
Run Code Online (Sandbox Code Playgroud)
不同之处在于硬链接文件.注意如何单独复制硬链接文件cp和与之一起单独复制tar.为了使差异更明显,请查看每个的inode:
alastair box:~/hack/cptest [1149]% ls -i cpdest
24690722 foo 24690723 foo-h 24690724 foo-s
alastair box:~/hack/cptest [1150]% ls -i tardest
24690801 foo 24690801 foo-h 24690802 foo-s
Run Code Online (Sandbox Code Playgroud)
可能还有其他理由喜欢tar,但这是一个很大的原因,至少如果你有广泛的硬链接文件.
小智 5
$ time { tar -cf - * | (cd ../bar; tar -xf - ); }
real 0m4.209s
user 0m0.724s
sys 0m3.380s
$ time { cp * ../baz/; }
real 0m18.727s
user 0m0.644s
sys 0m7.127s
$ time { tar -cf - * | (cd ../bar; tar -xf - ); }
real 3m44.007s
user 0m3.390s
sys 0m25.644s
$ time { cp * ../baz/; }
real 3m11.197s
user 0m0.023s
sys 0m9.576s
我猜这种现象是高度依赖于文件系统的.如果我是对的,你会发现专门研究众多小文件的文件系统(如reiserfs 3.6)和处理大文件的文件系统之间存在巨大差异.
(我在HFS +上运行了上述测试.)