tar: เพิ่มไฟล์และไดเร็กทอรีทั้งหมดในไดเร็กทอรีปัจจุบันซึ่งรวมถึง. svn และอื่น ๆ


91

ฉันพยายาม tar.gz ไดเรกทอรีและใช้

tar -czf workspace.tar.gz *

tar ที่ได้จะมี.svnไดเร็กทอรีในไดเร็กทอรีย่อย แต่ไม่อยู่ในไดเร็กทอรีปัจจุบัน (เนื่องจาก*ขยายเป็นไฟล์ 'มองเห็นได้' เท่านั้นก่อนที่จะถูกส่งไปยัง tar

ฉันพยายามที่จะ

tar -czf workspace.tar.gz .แต่แล้วฉันก็ได้รับข้อผิดพลาดเนื่องจาก "." มีการเปลี่ยนแปลงขณะอ่าน:

tar: ./workspace.tar.gz: file changed as we read it

มีเคล็ดลับในการ*จับคู่ไฟล์ทั้งหมด (รวมถึงจุดที่นำหน้า) ในไดเรกทอรีหรือไม่

(ใช้ bash บน Linux SLES-11 (2.6.27.19)


5
คำถามนี้อาจเป็นของ superuser?
Peter Jaric

คำตอบ:


78

อย่าสร้างไฟล์ tar ในไดเร็กทอรีที่คุณกำลังบรรจุ:

tar -czf /tmp/workspace.tar.gz .

ทำเคล็ดลับยกเว้นว่ามันจะแตกไฟล์ทั้งหมดจากไดเร็กทอรีปัจจุบันเมื่อคุณแตกไฟล์ ดีกว่าที่จะทำ:

cd ..
tar -czf workspace.tar.gz workspace

หรือหากคุณไม่ทราบชื่อไดเรกทอรีที่คุณอยู่:

base=$(basename $PWD)
cd ..
tar -czf $base.tar.gz $base

(สิ่งนี้ถือว่าคุณไม่ได้ติดตาม symlink เพื่อไปยังที่ที่คุณอยู่และเชลล์ไม่พยายามเดาคุณเป็นครั้งที่สองโดยการกระโดดถอยหลังผ่าน symlink - bashไม่น่าไว้วางใจในแง่นี้หากคุณต้องกังวลเกี่ยวกับเรื่องนั้น ใช้cd -P ..ทำไดเร็กทอรีการเปลี่ยนแปลงทางกายภาพโง่ที่มันไม่ใช่พฤติกรรมเริ่มต้นในมุมมองของฉัน - สับสนอย่างน้อยสำหรับผู้ที่cd ..ไม่เคยมีความหมายอื่น)


ความคิดเห็นหนึ่งในการสนทนากล่าวว่า:

ฉัน [... ] จำเป็นต้องยกเว้นไดเร็กทอรีด้านบนและฉัน [... ] จำเป็นต้องวาง tar ในไดเร็กทอรีฐาน

ส่วนแรกของความคิดเห็นไม่สมเหตุสมผล - หากไฟล์ tar มีไดเร็กทอรีปัจจุบันจะไม่ถูกสร้างขึ้นเมื่อคุณแยกไฟล์จากที่เก็บถาวรนั้นเนื่องจากตามคำนิยามแล้วไดเรกทอรีปัจจุบันมีอยู่แล้ว (ยกเว้นในสถานการณ์ที่แปลกมาก ).

ส่วนที่สองของความคิดเห็นสามารถจัดการได้ด้วยวิธีใดวิธีหนึ่ง:

  1. อย่างใดอย่างหนึ่ง: สร้างไฟล์ที่อื่น - /tmpเป็นตำแหน่งเดียวที่เป็นไปได้ - จากนั้นย้ายกลับไปยังตำแหน่งเดิมหลังจากเสร็จสิ้น
  2. หรือ: หากคุณใช้ GNU Tar ให้ใช้--exclude=workspace.tar.gzตัวเลือก สตริงหลัง=เป็นรูปแบบ - ตัวอย่างเป็นรูปแบบที่ง่ายที่สุด - การจับคู่แบบตรงทั้งหมด คุณอาจต้องระบุ--exclude=./workspace.tar.gzว่าคุณกำลังทำงานในไดเร็กทอรีปัจจุบันซึ่งขัดกับคำแนะนำหรือไม่ คุณอาจต้องระบุ--exclude=workspace/workspace.tar.gzว่าคุณกำลังดำเนินการหนึ่งระดับตามที่แนะนำหรือไม่ หากคุณมีไฟล์ tar หลายไฟล์ที่จะแยกออกให้ใช้ ' *' ในรูปแบบ--exclude=./*.gz.

1
คำตอบที่ดี แต่ฉันมีสถานการณ์ที่ฉันถูกบังคับให้เรียกใช้คำสั่งนี้ในไดเร็กทอรีที่ต้องบรรจุ ฉันมีสิทธิ์ไม่เพียงพอที่จะเรียกใช้งานภายนอก
Hexodus

สถานที่ที่เหมาะสำหรับการแพ็คคือ / tmp แน่นอน
Andre Fellows

46

หากคุณจริงๆไม่ต้องการที่จะรวมไดเรกทอรีชั้นนำใน tarball (และว่าโดยทั่วไปความคิดที่ไม่ดี):

tar czf workspace.tar.gz -C /path/to/workspace .

ฉันต้องการแยกไดเรกทอรีด้านบนและฉันจำเป็นต้องวาง tar ในไดเรกทอรีฐาน
ปาสเตอร์

@ มิชาสร้างสคริปต์ทุบตีเพื่อเก็บถาวรและคัดลอกไฟล์หลังจาก
Fedir RYKHTIK

2
คุณคิดถึง - ใน -czf ฉันคิดว่า
UpTheCreek

10
man tar: อาร์กิวเมนต์แรกของ tar ควรเป็นฟังก์ชัน ตัวอักษรตัวใดตัวAcdrtuxหนึ่งหรือชื่อฟังก์ชันแบบยาว ไม่จำเป็นต้องมีคำนำหน้าอักษรฟังก์ชัน-และอาจใช้ร่วมกับตัวเลือกอักษรตัวเดียวอื่น ๆ
rkhayrov

4
ยังใช้ไม่ได้ฉันยังมี "." เป็นไดเรกทอรีอันดับต้น ๆ ใน tarball ของฉัน
A.Gille

44

มีสองสามขั้นตอนที่ต้องดำเนินการ:

  1. แทนที่*ด้วย.เพื่อรวมไฟล์ที่ซ่อนอยู่ด้วย
  2. ในการสร้างไฟล์เก็บถาวรในไดเร็กทอรีเดียวกัน--exclude=workspace.tar.gzสามารถใช้เพื่อแยกไฟล์ที่เก็บถาวรได้
  3. เพื่อป้องกันtar: .: file changed as we read itข้อผิดพลาดเมื่อยังไม่ได้สร้างไฟล์เก็บถาวรตรวจสอบให้แน่ใจว่ามีอยู่ (เช่นกำลังใช้touch) ดังนั้น- ไม่รวมจึงตรงกับชื่อไฟล์ที่เก็บ (ไม่ตรงกับไฟล์ไม่มีอยู่)

รวมผลลัพธ์นี้ในสคริปต์ต่อไปนี้:

touch workspace.tar.gz
tar -czf workspace.tar.gz --exclude=workspace.tar.gz .

7
ฉันอ่านคำตอบและความคิดเห็นทั้งหมดและนี่เป็นวิธีที่ดีที่สุดในการสร้าง tarball ใน dir เดียวกัน จากคำตอบนี้ฉันก็เข้าใจว่าเหตุใดจึงเกิดข้อผิดพลาดนี้
Szymon Sadło

หากคุณต้องการที่จะเห็นความคืบหน้าในขณะที่มันบีบอัดไฟล์ tar ของคุณคุณสามารถเพิ่มธงชาติเพิ่มเติมสำหรับเช่นดังนั้น:--verbose -czvf
Mastrianni

19

ในไดเร็กทอรีต้องการบีบอัด (ไดเร็กทอรีปัจจุบัน) ลองสิ่งนี้:

tar -czf workspace.tar.gz . --exclude=./*.gz

2
แต่ตอนนี้มันบ่นว่าไฟล์ "." เปลี่ยนแปลงในขณะที่กำลังอ่าน แน่ใจได้หรือไม่ว่ารวมไฟล์ทั้งหมดแล้ว
Jaan

1
ซึ่งจะไม่รวม.gzไฟล์ทั้งหมดในไดเร็กทอรี
omerfarukdogan

12

คุณสามารถรวมไดเร็กทอรีที่ซ่อนไว้โดยย้อนกลับไดเร็กทอรีและทำ:

cd ..
tar czf workspace.tar.gz workspace

สมมติว่าไดเร็กทอรีที่คุณต้องการ gzip เรียกว่าพื้นที่ทำงาน


และหลีกเลี่ยงปัญหาไฟล์ที่เปลี่ยนแปลงด้วย
Jonathan Leffler

ไม่ทำงานเมื่อผู้ใช้ไม่มีสิทธิ์ในการเขียนในโฟลเดอร์หลัก
Joachim Wagner

@JoachimWagner เป๊ะ!
p01ymath

1
@JoachimWagner. หากคุณไม่ได้รับอนุญาตให้เขียนให้เปลี่ยนเป็น:tar -czf /path/to/where/you/do/have/permission/workspace.tar.gz workspace
bramp

1
ฉันต้องนำออก-ก่อนที่czfจะทำให้มันทำงาน มิฉะนั้นฉันได้รับCannot stat: No such file or directoryข้อความแสดงข้อผิดพลาด
Phemelo Khetho


5

อัปเดต:ฉันได้เพิ่มการแก้ไขสำหรับความคิดเห็นของ OP

tar -czf workspace.tar.gz .

แน่นอนจะเปลี่ยนไดเร็กทอรีปัจจุบัน แต่ทำไมไม่วางไฟล์ไว้ที่อื่นล่ะ?

tar -czf somewhereelse/workspace.tar.gz .
mv somewhereelse/workspace.tar.gz . # Update

ไฟล์จะได้รับการประมวลผลในภายหลังและจำเป็นต้องอยู่ในพื้นที่ทำงาน - ราคาเสนอค่อนข้างน่าเกลียด แต่ก็จำเป็น (ทั้งหมดนี้เป็นเพียงวิธีแก้ปัญหา ... )
Micha

ตกลงฉันจะเพิ่มการแก้ไขให้ :)
Peter Jaric

และถ้าคุณต้องการให้สามารถรันซ้ำได้ให้เพิ่ม 'rm workspace.tar.gz' ก่อนบรรทัด tar
Peter Jaric

หากคุณต้องการ tar ทั้งไดรฟ์ลงในไดรฟ์เดียวกันดูเหมือนว่าคุณไม่มีตัวเลือกมากมาย
BeeOnRope

4

จริงๆแล้วปัญหาอยู่ที่ตัวเลือกการบีบอัด เคล็ดลับคือท่อส่งผลน้ำมันดินไปยังคอมเพรสเซอร์แทนที่จะใช้ตัวเลือกในตัว นอกจากนี้ยังสามารถให้การบีบอัดที่ดีขึ้นเนื่องจากคุณสามารถตั้งค่าตัวเลือกการบีบอัดเพิ่มเติมได้

น้ำมันดินขั้นต่ำ:

tar --exclude=*.tar* -cf workspace.tar .

ท่อเข้ากับคอมเพรสเซอร์ที่คุณเลือก ตัวอย่างนี้เป็น verbose และใช้ xz ที่มีการบีบอัดสูงสุด:

tar --exclude=*.tar* -cv . | xz -9v >workspace.tar.xz

โซลูชันได้รับการทดสอบบน Ubuntu 14.04 และ Cygwin บน Windows 7 เป็นคำตอบของวิกิชุมชนดังนั้นอย่าลังเลที่จะแก้ไขหากคุณพบข้อผิดพลาด


ขอขอบคุณ! บันทึกชีวิตแม่
สตีเวน

2

ปัญหาเกี่ยวกับวิธีแก้ไขส่วนใหญ่ที่ให้ไว้ที่นี่คือ tar มี./อยู่ในการขอทานทุกรายการ ดังนั้นจึงส่งผลให้มี.ไดเร็กทอรีเมื่อเปิดผ่าน GUI compressor ดังนั้นสิ่งที่ฉันทำคือ:

ls -1A | xargs -d "\n" tar cfz my.tar.gz

หากคุณมีmy.tar.gzอยู่ในไดเร็กทอรีปัจจุบันคุณอาจต้องการ grep สิ่งนี้:

ls -1A | grep -v my.tar.gz | xargs -d "\n" tar cfz my.tar.gz

โปรดทราบว่า xargs มีขีด จำกัด ที่แน่นอน (ดูxargs --show-limits) ดังนั้นวิธีนี้จะใช้ไม่ได้หากคุณพยายามสร้างแพ็คเกจที่มีรายการ (ไดเร็กทอรีและไฟล์) จำนวนมากบนไดเร็กทอรีที่คุณกำลังพยายาม tar


1

เป็นคำถามที่ดี ใน ZSH คุณสามารถใช้ตัวปรับแต่ง globbing (D)ซึ่งย่อมาจาก "dotfiles" เปรียบเทียบ:

ls $HOME/*

และ

ls $HOME/*(D)

สิ่งนี้ถูกต้องยกเว้นรายการไดเร็กทอรีพิเศษ.และ... ใน Bash คุณสามารถใช้.*เพื่อรวม dotfiles อย่างชัดเจน:

ls $HOME/* $HOME/.*

แต่นั่นรวมถึง.และ..เช่นกันดังนั้นจึงไม่ใช่สิ่งที่คุณกำลังมองหา ฉันแน่ใจว่ามีวิธีบางอย่างในการ*จับคู่ dotfiles ใน bash ด้วย


ใน bash ใช้.??*เพื่อจับคู่ไฟล์ dot ทั้งหมดที่ไม่ใช่.และ... ที่ไม่ได้รับไฟล์จุดอักขระเดียว (เช่น.a) .[^.]*ที่จะได้รับเหล่านั้นมากเกินไปให้ใช้ความซับซ้อนมากขึ้น
Scott Minster

1

อีกวิธีหนึ่งโดยสมมติว่าจำนวนรายการในโฟลเดอร์ไม่มาก:

tar -czf workspace.tar.gz `ls -A`

( ls -Aพิมพ์ไฟล์ปกติและไฟล์ที่ซ่อนไว้ แต่ไม่พิมพ์ "." และ ".. " เหมือนls -aเดิม)


0
tar -czf workspace.tar.gz .??* *

การระบุ.??*จะรวมไฟล์และไดเร็กทอรี "dot" ที่มีอักขระอย่างน้อย 2 ตัวหลังจุด ด้านล่างคือจะไม่รวมไฟล์ / ไดเรกทอรีที่มีอักขระตัวเดียวหลังจุดเช่น.aถ้ามี


0

หากพื้นที่ว่างบนดิสก์ไม่ใช่ปัญหาสิ่งนี้อาจเป็นสิ่งที่ทำได้ง่ายมาก:

mkdir backup
cp -r ./* backup
tar -zcvf backup.tar.gz ./backup

0

มีสถานการณ์ที่คล้ายกันกับตัวเอง ฉันคิดว่าเป็นการดีที่สุดที่จะสร้าง tar ที่อื่นจากนั้นใช้ -C เพื่อบอก tar ไดเรกทอรีฐานสำหรับไฟล์บีบอัด ตัวอย่าง:

tar -cjf workspace.tar.gz -C <path_to_workspace> $(ls -A <path_to_workspace>)

วิธีนี้ไม่จำเป็นต้องยกเว้น tarfile ของคุณเอง ตามที่ระบุไว้ในความคิดเห็นอื่น ๆ -A จะแสดงรายการไฟล์ที่ซ่อนอยู่


0

10 ปีต่อมาคุณมีทางเลือกอื่นที่tarแสดงด้วย Git 2.30 (Q1 2021) ซึ่งใช้ " git archive" ( man )ในการผลิต tarball แทน tar
(คุณไม่จำเป็นต้องใช้ Git 2.30 เพื่อใช้ทางเลือกนั้น)

ดูกระทำ 4813277 (11 ตุลาคม 2020) และกระทำ 93e7031 (10 ตุลาคม 2020) โดยRené Scharfe (rscharfe )
(รวมโดยJunio C Hamano - gitster-ในการกระทำ 63e5273 , 27 ตุลาคม 2020)

Makefile: ใช้ git init / เพิ่ม / กระทำ / เก็บถาวรสำหรับ dist-doc

ลงนามโดย: René Scharfe

ลดการพึ่งพาเครื่องมือภายนอกโดยการสร้างไฟล์เก็บถาวรการแจกจ่ายสำหรับเอกสาร HTML และจัดการโดยใช้คำสั่ง( man )แทน tar สิ่งนี้ทำให้รายการเก็บถาวรมีข้อมูลเมตาเดียวกับที่อยู่ในไฟล์เก็บถาวรสำหรับไบนารีgit

แทนที่จะเป็น:

tar cf ../archive.tar .

คุณสามารถทำได้โดยใช้ Git เท่านั้น:

git -C workspace init
git -C workspace add .
git -C workspace commit -m workspace
git -C workspace archive --format=tar --prefix=./ HEAD^{tree} > workspace.tar
rm -Rf workspace/.git

ที่เสนอในตอนแรกเนื่องจากตามที่อธิบายไว้ที่นี่แพลตฟอร์มที่แปลกใหม่บางแพลตฟอร์มอาจมีการกระจายน้ำมันดินแบบเก่าและไม่มีตัวเลือก


-1

การใช้findอาจเป็นวิธีที่ง่ายที่สุด:

find . -maxdepth 1 -exec tar zcvf workspace.tar.gz {} \+

find . -maxdepth 1จะพบไฟล์ทั้งหมดในไดเรกทอรี / / symlinks / etc -execในไดเรกทอรีปัจจุบันและเรียกใช้คำสั่งที่ระบุโดย {}ในคำสั่งหมายถึงรายชื่อไฟล์ที่นี่และ\+หมายความว่าคำสั่งจะถูกเรียกใช้เป็น:

tar zcvf workspace.tar.gz .file1 .file2 .dir3

แทน

tar zcvf workspace.tar.gz .file1
tar zcvf workspace.tar.gz .file2
tar zcvf workspace.tar.gz .dir3

-J คือ --xz ในคู่มือ; รวมกับ -c เป็นเพียงจุดเริ่มต้นของสิ่งที่คอมพิวเตอร์เรียกว่า "สนุก" :)
Ricalsin

ฮ่าฮ่ามินิเซิร์ฟเวอร์ที่บ้านของฉันถูก จำกัด ด้วยเนื้อที่ดิสก์มากกว่าซีพียู :) ข้อดีคือ; ฉันจะเปลี่ยนไปใช้ gzip
Andrew Gunnerson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.