วิธีการ untar อย่างปลอดภัยโดยไม่สร้างมลพิษไดเรกทอรีปัจจุบันในกรณีของ tarbomb?


33

โครงการปล่อยเกียรติจดหมายเหตุน้ำมันดินที่มีไดเรกทอรีเดียวเช่นzyrgus-3.18.tar.gzมีzyrgus-3.18โฟลเดอร์ซึ่งจะมีsrc, build, distฯลฯ

แต่พังค์บางโครงการใส่ทุกอย่างไว้ที่ราก: '- (ซึ่งจะทำให้เกิดความยุ่งเหยิงโดยรวมเมื่อยกเลิกการเก็บถาวรการสร้างโฟลเดอร์ด้วยตนเองทุกครั้งเป็นความเจ็บปวด

  • มีวิธีที่รวดเร็วในการบอกว่าไฟล์. tar หรือ. tar.gz มีมากกว่าหนึ่งไดเรกทอรีที่รากหรือไม่ แม้จะเป็นไฟล์เก็บถาวรขนาดใหญ่
  • หรือดียิ่งขึ้นมีเครื่องมือที่ในกรณีเช่นนี้จะสร้างไดเรกทอรี (ชื่อของไฟล์เก็บถาวรที่ไม่มีนามสกุล) และใส่ทุกอย่างไว้ข้างในหรือไม่?


2
ฉันคิดว่าบรรจุภัณฑ์ที่เสียหายมีค่ารายงานข้อผิดพลาดแก่ผู้เขียนแพ็คเกจ

14
ฉันเคยมีประวัติ (ตั้งแต่ช่วงกลางยุค 90) เพียงไม่ได้รับการแปลลงในไดเรกทอรีย่อยเสมอ หากทั้งหมดนั้นใส่ไว้ในไดเรกทอรีเดียว (ตามที่ควรจะเป็น) เนื้อหานั้นจะสามารถย้ายไปยังตำแหน่งที่ถูกต้องด้วย mv จากนั้นคุณสามารถลบไดเรกทอรีพิเศษที่ไม่จำเป็น สองขั้นตอนพิเศษใช่ แต่มันเต้นล้างระเบียบจากไฟล์ tar ที่ทำผิด
TED

6
But some punk projects put everything at the root :'-(และบางโครงการพังค์ใส่ทุกอย่างไว้ในโฟลเดอร์โดยไม่จำเป็นอย่างสมบูรณ์โดยพิจารณาว่าพวกเขาได้วางทุกอย่างไว้ในที่เก็บข้อมูลที่มีการปิดล้อมดังนั้นเมื่อคุณดาวน์โหลดและแตกไฟล์ลงในโฟลเดอร์ของตัวเองเหมือนกับที่ผู้ใช้ฉลาด ๆ เนื้อหาฝังอีกชั้นหนึ่งลง ;-)
Mason Wheeler

2
@MasonWheeler มีชนิดของ "มาตรฐาน de-facto" สำหรับเก็บถาวร tar ที่จะมีทุกอย่างในหนึ่งโฟลเดอร์ภายใน
glglgl

คำตอบ:


30

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

แยกไฟล์เก็บถาวร

patool extract archive.tar

patool formatsที่จะได้รับรายชื่อของรูปแบบที่สนับสนุนการใช้งาน


FYI: พบมันที่sourceforge.net/projects/patool มันเป็นรอบต่อนาทีและฉันเคยalienแปลงมันให้เป็น deb สำหรับ Ubuntu
โจ

patoolควรอยู่ใน repos สำหรับ Debian และ Ubuntu หากคุณใช้งานเวอร์ชันปัจจุบัน
Marco

12

คุณสามารถทำสิ่งที่ชอบ

tar tf thefile.tar | cut -d/ -f1 | sort -u

เพื่อดูสิ่งที่รายการระดับบนสุดน้ำมันดินมี; ไปที่ท่อเพื่อwc -lตรวจสอบว่ามีมากกว่าหนึ่ง โปรดทราบว่ามีบางกรณีที่สิ่งนี้จะล้มเหลวเช่นหาก tar มีพา ธ ไฟล์ของฟอร์มsomedir/whateverและยัง./somedir/whatever(หรือบางอย่างที่บ้าคลั่ง); สิ่งนี้ควรเป็นเรื่องแปลก

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

หากคุณทำสิ่งนี้แบบโต้ตอบและไฟล์อาจมีขนาดใหญ่คุณสามารถเปลี่ยนsort -uเป็น+ uniqและถ้าพิมพ์ออกมามากกว่าหนึ่งสิ่งControlC


2
sort | uniqsort -uสามารถลงไป
Marco

4
ถ้าคุณต้องการที่จะทำuniq -c
cas

7

คุณทำได้:

pax <some.tar

... เพื่อแสดงรายการเนื้อหาของtarไฟล์

หากคุณต้องการรู้ว่ามันไปได้กี่ระดับคุณสามารถทำได้:

pax <some.tar | tr -dc /\\n | sort -r | head -n1

คุณสามารถห้ามการระเบิดอย่างชัดเจนด้วยการสกัดด้วย:

mkdir some.tar
pax -'rs|^|some.tar/|' <some.tar

2

สิ่งนี้ควรทำในสิ่งที่คุณต้องการ ฉันแน่ใจว่าบางคนสามารถปรับปรุงได้ ในตัวอย่างเหล่านี้ฉันถือว่าการเก็บถาวร tar ที่บีบอัด gzip เนื่องจากนี่เป็นเรื่องธรรมดาที่สุด

คุณต้องการไฟล์เก็บถาวรที่ไม่มีโหนด sibling ในแผนผังไดเร็กทอรีระดับราก

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

บรรทัดแรกในรายการเนื้อหา tar จะให้รูปแบบขั้นต่ำที่คุณต้องตรวจสอบ นี่คือ BASEPATH

BASEPATH=$(tar ztf example.tar.gz | (read line; echo $line))

จากนั้นในการทดสอบสำหรับ tarballs ระเบิดคุณจะต้องตรวจสอบว่าใด ๆบรรทัดของรายการเนื้อหาน้ำมันดินไม่ได้เริ่มต้นด้วย basepath

tar ztf example.tar.gz | grep -qv "^${BASEPATH}"

เปลี่ยนสิ่งนี้เป็นฟังก์ชั่นเชลล์:

is_explosive() {
    TARBALL_NAME=$1
    tar ztf "${TARBALL_NAME}" | grep -qv "^$(tar ztf "${TARBALL_NAME}" | (read line; echo ${line}))"
    return $?
}

จากตรงนี้คุณสามารถเขียนฟังก์ชันการแยกไฟล์เก็บถาวร tar ปลอดภัย

is_explosive() {
    TARBALL_NAME=$1
    tar ztf "${TARBALL_NAME}" | grep -qv "^$(tar ztf "${TARBALL_NAME}" | (read line; echo ${line}))"
    return $?
}

safe_tar_x() {
    TARBALL_NAME=$1
    if is_explosive ${TARBALL_NAME}; then
        SUBDIR=${TARBALL_NAME%.tar.gz}
        SUBDIR=${SUBDIR##*/}
        mkdir "${SUBDIR}"
        echo "WARNING: This tarball is explosive. Opening in subdirectory, ${SUBDIR}, for safety." >&2
    else
        SUBDIR="."
    fi
    # Tar quirks: "--directory" must be last, and using more than
    #     one option group requires that all groups start with a dash.
    tar -zxf "${TARBALL_NAME}" --directory "${SUBDIR}"
    return $?
}

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