Bash
為什麼 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
現在-> 甚至是tought,我已經更改為 dir
$des/bin
,它仍然給出來自根目錄的絕對路徑,但它應該給出來自目前目錄的相對$des/bin
路徑(在 之後-C
),為什麼?
由於
$des
contains/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
(假設 GNU
tar
或兼容)。如果文件列表足夠小,則不需要
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()