为什么 tar 使用绝对路径,即使我已通过 -C 更改为 dir?

为什么 tar 使用绝对路径,即使我已通过 -C 更改为 dir?

有这个:

$ls $des/bin
a.c           analysis.hpp  classify.hpp  main.cpp   split.hpp
a.cpp         a.out         grade.cpp     main.out   student.cpp
analysis.cpp  classify.cpp  grade.hpp     split.cpp  student.hpp
$ for i in $des/bin/*{hpp,cpp}; do echo $i; done | tar czvf files.tar.gz -C $des/bin -T -

/home/user/Desktop/bin/analysis.hpp
/home/user/Desktop/bin/classify.hpp
/home/user/Desktop/bin/grade.hpp
/home/user/Desktop/bin/split.hpp
/home/user/Desktop/bin/student.hpp
/home/user/Desktop/bin/a.cpp
/home/user/Desktop/bin/analysis.cpp
/home/user/Desktop/bin/classify.cpp
/home/user/Desktop/bin/grade.cpp
/home/user/Desktop/bin/main.cpp
/home/user/Desktop/bin/split.cpp
/home/user/Desktop/bin/student.cpp

现在 -> 即便如此,我也有改变了到 dir $des/bin,它仍然给出从 root 开始的绝对路径,但它应该给出相对的从当前目录开始的路径(在$des/bin后面-C),为什么?

答案1

由于$descontains /home/user/Desktop,您要传递到的文件列表tar -T -是:

/home/user/Desktop/bin/analysis.hpp
/home/user/Desktop/bin/classify.hpp
/home/user/Desktop/bin/grade.hpp
[...]

您需要该列表为:

analysis.hpp
classify.hpp
grade.hpp
[...]

如果这是您想要存储在存档中的路径。

通常,您会这样做:

(
  cd -P -- "$des/bin" &&
    printf '%s\0' *.[hc]pp |
      tar --null -T - -zcvf -
) > file.tar.gz

(假设 GNUtar或兼容)。

如果文件列表足够小,则不需要printf.你可以这样做:

(
  cd -P -- "$des/bin" &&
    tar -czvf - -- *.[hc]pp
) > file.tar.gz

或者压缩为最短的形式:

(cd -P -- "$des/bin"&&tar czvf - -- *.[hc]pp)>file.tar.gz

如果文件数量非常大*.[hc]pp,则可能会超出系统调用可以采用的 cmdline+environ 的最大大小execve()printf在 shell 中使用printf内置函数可以bash解决这个问题,因为内置函数不是通过execve()系统调用执行的,因此不受该限制的影响。

答案2

仅限 GNU tar

tar --transform "s,.*/\(.*\),$des/bin/\1," -czf ~/files.tar.gz "$des"/bin/*.[ch]pp

可能是您正在寻找的内容(其中第一个$des/bin/可以替换为您喜欢的任何内容并\1代表文件名)

tar --transform 's,.*/\(.*\),\1,' -czf ~/files.tar.gz "$des"/bin/*.[ch]pp

相关内容