Bash

為什麼 tar 使用絕對路徑,即使我已通過 -C 更改為 dir?

  • July 30, 2020

有這個:

$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

現在-> 甚至是tought,我已經更改為 dir $des/bin,它仍然給出來自根目錄的絕對路徑,但它應該給出來自目前目錄的相對$des/bin路徑(在 之後-C),為什麼?

由於$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文件,則可能超過execve()系統呼叫可以採用的 cmdline+environ 的最大大小。在類似內置printf的外殼中使用可以解決這個問題,因為內置不是通過系統呼叫執行的,因此不受該限制的影響。printf``bash``execve()

引用自:https://unix.stackexchange.com/questions/600901