因此,您的尝试是: find... | xargs tar czvf file.tgz
可能最终会在 xargs 对“ tar”的每次调用中覆盖“ file.tgz”,并且最终只会得到最后一次调用!(所选择的解决方案使用 GNU-T 特殊参数来避免这个问题,但并不是每个人都有可用的 GNU tar)
你可以这样做:
find . -type f -print0 | xargs -0 tar -rvf backup.tar
gzip backup.tar
Cygwin 上的问题证明:
$ mkdir test
$ cd test
$ seq 1 10000 | sed -e "s/^/long_filename_/" | xargs touch
# create the files
$ seq 1 10000 | sed -e "s/^/long_filename_/" | xargs tar czvf archive.tgz
# will invoke tar several time as it can'f fit 10000 long filenames into 1
$ tar tzvf archive.tgz | wc -l
60
# in my own machine, I end up with only the 60 last filenames,
# as the last invocation of tar by xargs overwrote the previous one(s)
# proper way to invoke tar: with -r (which append to an existing tar file, whereas c would overwrite it)
# caveat: you can't have it compressed (you can't add to a compressed archive)
$ seq 1 10000 | sed -e "s/^/long_filename_/" | xargs tar rvf archive.tar #-r, and without z
$ gzip archive.tar
$ tar tzvf archive.tar.gz | wc -l
10000
# we have all our files, despite xargs making several invocations of the tar command
注意: xargs 的行为是一个众所周知的玩笑,这也是为什么,当有人想做:
find .... | xargs grep "regex"
他们不得不这样写:
find ..... | xargs grep "regex" /dev/null
That way, even if the last invocation of grep by xargs appends only 1 filename, grep sees at least 2 filenames (as each time it has: /dev/null, where it won't find anything, and the filename(s) appended by xargs after it) and thus will always display the file names when something maches "regex". Otherwise you may end up with the last results showing matches without a filename in front.