ห้ามฝากไดเรกทอรีไว้ แต่อย่าเก็บเส้นทางที่สมบูรณ์แบบไว้ในที่เก็บถาวร


277

ฉันมีคำสั่งต่อไปนี้ในส่วนของเชลล์สคริปต์สำรอง:

tar -cjf site1.bz2 /var/www/site1/

เมื่อฉันแสดงรายการเนื้อหาของไฟล์เก็บถาวรฉันจะได้รับ:

tar -tf site1.bz2
var/www/site1/style.css
var/www/site1/index.html
var/www/site1/page2.html
var/www/site1/page3.html
var/www/site1/images/img1.png
var/www/site1/images/img2.png
var/www/site1/subdir/index.html

แต่ฉันต้องการที่จะลบส่วน/var/www/site1จากไดเรกทอรีและชื่อไฟล์ภายในที่เก็บเพื่อลดความยุ่งยากในการสกัดและหลีกเลี่ยงโครงสร้างไดเรกทอรีคงที่ไร้ประโยชน์ ไม่เคยรู้ในกรณีที่ฉันจะแยกเว็บไซต์ที่/var/wwwสำรองไว้ในที่ที่ไม่มีการจัดเก็บข้อมูลเว็บไว้

สำหรับตัวอย่างข้างต้นฉันต้องการ:

tar -tf site1.bz2
style.css
index.html
page2.html
page3.html
images/img1.png
images/img2.png
subdir/index.html

ดังนั้นเมื่อฉันแตกไฟล์จะถูกแตกในไดเรกทอรีปัจจุบันและฉันไม่จำเป็นต้องย้ายไฟล์ที่ถูกแยกหลังจากนั้นและเพื่อให้โครงสร้างไดเรกทอรีย่อยถูกเก็บรักษาไว้

มีคำถามมากมายเกี่ยวกับ tar และการสำรองข้อมูลในstackoverflowและที่อื่น ๆ บนเว็บ แต่ส่วนใหญ่ขอให้วางโครงสร้างไดเรกทอรีย่อยทั้งหมด (แบน) หรือเพียงแค่เพิ่มหรือลบชื่อเริ่มต้น / ในชื่อ (I don ' ไม่รู้ว่ามันจะเปลี่ยนไปเมื่อสกัด) แต่ไม่มาก

หลังจากอ่านคำตอบบางส่วนที่พบที่นี่และที่นั่นพร้อมกับคู่มือแล้วฉันลอง:

tar -cjf site1.bz2 -C . /var/www/site1/
tar -cjf site1.bz2 -C / /var/www/site1/
tar -cjf site1.bz2 -C /var/www/site1/ /var/www/site1/
tar -cjf site1.bz2 --strip-components=3 /var/www/site1/

แต่ไม่มีพวกเขาทำงานตามที่ฉันต้องการ บางคนไม่ทำอะไรเลยบางคนไม่เก็บถาวรไดเรกทอรีย่อยอีกต่อไป

มันอยู่ในเชลล์สำรองสคริปต์ที่เปิดตัวโดย Cron ดังนั้นฉันจึงไม่ทราบว่าผู้ใช้รายไหนพา ธ และไดเรกทอรีปัจจุบันคืออะไรดังนั้นจึงจำเป็นต้องเขียนเส้นทางที่แน่นอนสำหรับทุกสิ่งและไม่ต้องการเปลี่ยนไดเรกทอรีปัจจุบัน เพื่อหลีกเลี่ยงการทำลายบางสิ่งบางอย่างเพิ่มเติมในสคริปต์ (เพราะมันไม่ได้เป็นเพียงแค่เว็บไซต์สำรองข้อมูล แต่ยังรวมถึงฐานข้อมูลแล้วส่งสิ่งนั้นไปยัง FTP ฯลฯ )

ทำอย่างไรจึงจะได้สิ่งนี้?

ฉันเพิ่งเข้าใจผิดว่าตัวเลือก -C ทำงานอย่างไร



ดี-Cก็หมายความว่า "การเปลี่ยนแปลงไดเรกทอรี" ในขณะที่การเปลี่ยนเส้นทาง (หรือ prefixing) --transformสามารถทำได้โดยเฉพาะ Rif superuser.com/questions/595510/prepend-prefix-in-tar/595512คุณสามารถง่าย -C (เปลี่ยนไดเรกทอรี) และ - เปลี่ยนรูปมัน: `` tar tar cjf site1.bz2 --transform "s / ^ \. \ // $ targetbase / "-C / var / www / site1 `` `
Daniele Cruciani

นี่เป็นคำถามที่ดีมากและน่าเศร้าที่ไม่มีคำตอบในวันนี้ที่น่าพอใจ เรายังไม่ได้รับการตอบรับจากคนที่มีปัญญาว่าเราจะแยกไฟล์ style.css (ตัวอย่างด้านบน) ลงในไดเรกทอรีปัจจุบันได้อย่างไรโดยไม่มีการอ้างอิงไปยังตำแหน่งดั้งเดิมหรือไดเรกทอรีต้นไม้? ฉันไม่ต้องการทำให้ไดเรกทอรีปัจจุบันยุ่งเหยิงด้วยโครงสร้างต้นไม้ใหม่ที่ไม่ต้องการ ฟังดูเหมือนการบกพร่องอย่างร้ายแรงของ tarball ที่ถูกมองข้ามมาหลายปี
elmclose

คำตอบ:


383
tar -cjf site1.tar.bz2 -C /var/www/site1 .

ในตัวอย่างข้างต้น tar จะเปลี่ยนไปที่ไดเรกทอรี/var/www/site1ก่อนทำสิ่งนั้นเพราะ-C /var/www/site1ได้รับตัวเลือก

จากman tar:

OTHER OPTIONS

  -C, --directory DIR
       change to directory DIR

152
อย่าพลาดจุดท้ายนั่นเป็นเรื่องสำคัญ ;-)
Freedom_Ben

9
ถ้าคุณต้องการเลือกไฟล์ที่จะสำรองตาม wildcard ล่ะ -C / var / www / site1 * .dat ไม่ทำงาน :(
Andy Lorenz

16
จุดบอกtarให้เก็บทุกอย่างในไดเรกทอรีปัจจุบัน และ-Cตั้งค่าไดเรกทอรีปัจจุบัน
Lars Brinkhoff

21
มันใช้งานได้ดี ฉันพบว่ามีประโยชน์ในการรักษาชื่อไดเรกทอรี (ไม่ใช่เส้นทางแบบเต็ม) ดังนั้นฉันจึงทำสิ่งต่อไปนี้: tar -czvf site1.tar.gz -C /var/www/ site1(สังเกตช่องว่างฉันยังคงใช้ -C, เพื่อ cd ไปยัง parent dir และระบุ dir to tar แทนจุด)
jorfus

9
ฉันได้รับจุดนำในเส้นทางของ tar เช่น./foldersนี้จะลบได้อย่างไร
Mika571

39

ตัวเลือกใช้-Cงานได้; เพื่อความชัดเจนฉันจะโพสต์ 2 ตัวอย่าง:

  1. การสร้าง tarball ที่ไม่มีเส้นทางเต็ม: เส้นทางแบบเต็ม/home/testuser/workspace/project/application.warและสิ่งที่เราต้องการเป็นเช่นproject/application.warนั้น:

    tar -cvf output_filename.tar  -C /home/testuser/workspace project

    หมายเหตุ: มีช่องว่างระหว่างworkspaceและproject; tar projectจะเข้ามาแทนที่เส้นทางที่เต็มไปด้วยเพียง

  2. สกัด tarball ด้วยการเปลี่ยนเส้นทางเป้าหมาย (ค่าเริ่มต้น.คือไดเรกทอรีปัจจุบัน)

    tar -xvf output_filename.tar -C /home/deploy/

    tarจะแยก tarball ตามเส้นทางที่กำหนดและรักษาเส้นทางการสร้าง ในตัวอย่างไฟล์จะถูกแยกไปapplication.war/home/deploy/project/application.war

    /home/deploy: ได้รับจากสารสกัด
    project: รับเมื่อสร้าง tarball

หมายเหตุ: หากคุณต้องการวาง tarball ที่สร้างขึ้นในไดเรกทอรีเป้าหมายคุณเพียงแค่เพิ่มเส้นทางเป้าหมายก่อนชื่อ tarball เช่น:

tar -cvf /path/to/place/output_filename.tar  -C /home/testuser/workspace project

1
จะเพิ่มไวด์การ์ดสำหรับการเลือกไฟล์ในตัวอย่างสุดท้ายได้อย่างไร?
ศิวะ

ปัญหาเกี่ยวกับ wildcards คือเชลล์จะขยายไปยังชื่อไฟล์ที่ตรงกันและ tar นั้นจะไม่ขยายออกหากมีการอ้างถึง ...
Gert van den Berg

ฉันลองสิ่งนี้บน Ubuntu 18.04 และไม่มีโชค ฉันไม่แน่ใจว่าสิ่งที่ฉันหายไป stdout ของฉันแสดงอย่างถูกต้องเมื่อฉันจัดทำมัน แต่เมื่อฉัน untar มันก็ยังมีเส้นทางแบบเต็ม
sdc

14

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

tar target_path/file.tar.gz -C source_path/source_dir

ดังนั้นโซลูชันที่สอดคล้องและมีประสิทธิภาพคือไปcdยัง source_path (พาเรนต์ไดเร็กทอรีของ source_dir) และรัน

tar target_path/file.tar.gz source_dir

หรือ

tar -cf target_path/file.tar.gz source_dir

ในสคริปต์ของคุณ สิ่งนี้จะลบคำนำหน้าเส้นทางแบบสัมบูรณ์ในโครงสร้างไดเรกทอรีของไฟล์ tar.gz ของคุณ


1
การใช้ตัวเลือก -C DIDนำหน้าสัมบูรณ์พา ธ สัมบูรณ์ภายในไฟล์ tar.gz ที่สร้างขึ้นบน fedora 29. คำตอบของคุณเฉพาะกับบางระบบหรือไม่?
EL_DON

@EL_DON: ฉันไม่ได้ทดสอบตัวเลือก -C บน Fedora แต่ซอฟต์แวร์แอปพลิเคชั่น tar ควรใช้งานได้ดีกับทุกแพลตฟอร์มยกเว้นว่าเป็นข้อผิดพลาดในแอปพลิเคชัน tar - ตัวเลือกฉันทดสอบบน Mac 10.8 และ Mac 10.13 และ Ubuntu (รุ่นที่ฉันจำไม่ได้) แต่ในฐานะของ tar v2.8.3 คำสั่งจะถูกเปลี่ยนเป็น tar -cf target_path / file.tar.gz source_dir และหากคุณเพิ่มตัวเลือก -C คำสั่งนั้นจะไม่ลบคำนำหน้าเส้นทางแบบสัมบูรณ์ภายในไฟล์ tar.gz ที่สร้างขึ้น
Chinthaka Senanayaka

ฉันทดสอบอีกครั้งในระบบ centOS หลังจากสร้างเส้นทางทั้งหมดในตัวอย่างและเรียกใช้คำสั่ง (พร้อม-cvfเพิ่มหลังจากtar) ฉันพบว่าไฟล์ tar.gz ที่ได้นั้นไม่มีเส้นทางที่แน่นอนอยู่ข้างในซึ่งสอดคล้องกับคำตอบอื่น ๆ หากคุณคิดว่า tar เสียหรือล้าสมัยกับทั้งสองระบบที่ฉันใช้ในการทดสอบโปรดเชื่อมโยงไปยังเอกสารที่จะสนับสนุนคำตอบของคุณ ฉันคิดว่า-Cตัวเลือกการเปลี่ยนแปลงไดเรกทอรีก่อนที่จะดำเนินการ (เหมือนคำตอบอื่น ๆ ) เมื่อฉันละเว้นมัน tar พยายามที่จะเพิ่มขยะจากรวมทั้งเส้นทางจากที่เริ่มต้นจาก./ ./
EL_DON

ฉันใช้เอกสารนี้: linux.die.net/man/1/tar ใช่หมอบอกว่า -C จะเปลี่ยนเส้นทาง แต่ใน Mac 10.13 ของฉันมันใช้งานไม่ได้ นี่อาจเป็นพฤติกรรมที่ไม่สอดคล้องกันของแอป tar นั่นหมายความว่านี่เป็นข้อผิดพลาด หากคุณกำลังเขียนเชลล์สคริปต์เพื่อให้ทำงานบนแพลตฟอร์มยูนิกซ์ทั้งหมดควรที่จะปลอดภัยด้วยการรันโค้ดที่จะทำงานบนระบบปฏิบัติการทั้งหมด
Chinthaka Senanayaka

คำตอบของคุณไม่ได้บอกว่าอาจมีข้อผิดพลาดและวิธีแก้ปัญหาที่มีประสิทธิภาพมากขึ้นสำหรับความเข้ากันได้ข้ามแพลตฟอร์มคือสิ่งcdแรก คำตอบของคุณบอกว่าเครื่องมือทำงานในลักษณะตรงกันข้ามกับที่เอกสารบอกว่าทำงานได้ดีและทำงานอย่างไรในระบบของฉันดังนั้นจึงเป็นคำตอบที่ผิด คุณสามารถแก้ไขได้อย่างง่ายดาย
EL_DON

7

คำสั่งต่อไปนี้จะสร้างไดเรกทอรีราก "." และวางไฟล์ทั้งหมดจากไดเรกทอรีที่ระบุลงไป

tar -cjf site1.tar.bz2 -C /var/www/site1 .

หากคุณต้องการใส่ไฟล์ทั้งหมดลงในรูทของไฟล์ tar @chinthaka นั้นถูกต้อง เพียงเข้าสู่ไดเรกทอรีและทำ:

tar -cjf target_path/file.tar.gz *

สิ่งนี้จะนำไฟล์ทั้งหมดใน cwd ไปที่ไฟล์ tar เป็นไฟล์รูท


1
การใช้ * จะไม่บันทึก "ไฟล์" .files หรือ. โฟลเดอร์ใด ๆ (fyi โดยใช้ -C พร้อมกับ * ล้มเหลวเชลล์จะขยาย dir ปัจจุบันไม่ใช่ -C dir)
Xen2050

1

การใช้ "จุด" นำไปสู่การสร้างโฟลเดอร์ชื่อ "จุด" (บน Ubuntu 16)

tar -tf site1.bz2 -C /var/www/site1/ .

ฉันจัดการกับมันในรายละเอียดเพิ่มเติมและเตรียมตัวอย่าง การบันทึกแบบหลายบรรทัดรวมถึงข้อยกเว้น

tar -tf site1.bz2\
    -C /var/www/site1/ style.css\
    -C /var/www/site1/ index.html\
    -C /var/www/site1/ page2.html\
    -C /var/www/site1/ page3.html\
    --exclude=images/*.zip\
    -C /var/www/site1/ images/
    -C /var/www/site1/ subdir/
/

เหตุใดคุณจึงเรียกมันว่า "ชี้" มันเป็นเพียง.ไดเรกทอรีปัจจุบัน ในบริบทของtar.gzโครงสร้างนั่นเป็นเพียงระดับฐาน / รูท / ระดับบนใช่ไหม
EL_DON

ดูภาพรวมสำหรับรายละเอียดของภาพ วิธีการของฉันถูกต้องกว่าที่จะใช้มันเป็นความคิดของฉัน
Sergey Asachev

0

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

tar -cjf site1.bz2 -C /var/www/ site1
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.