Bagaimana cara untar dengan aman, tanpa mencemari direktori saat ini dalam kasus tarbomb?

33

Proyek terhormat merilis arsip tar yang mengandung satu direktori, misalnya zyrgus-3.18.tar.gzberisi zyrgus-3.18folder yang pada gilirannya berisi src, build, dist, dll

Tetapi beberapa proyek punk menempatkan semuanya pada root: '- (Ini menghasilkan kekacauan total ketika membatalkan pengarsipan. Membuat folder secara manual setiap kali terasa menyebalkan, dan hampir tidak perlu sepanjang waktu.

  • Apakah ada cara super cepat untuk mengetahui apakah file .tar atau .tar.gz berisi lebih dari satu direktori pada akarnya? Bahkan untuk arsip besar.
  • Atau bahkan lebih baik, adakah alat yang dalam kasus seperti itu akan membuat direktori (nama arsip tanpa ekstensi) dan meletakkan semuanya di dalamnya?
Nicolas Raoul
sumber
2
Saya pikir kemasan rusak bernilai laporan bug untuk penulis paket.
14
Saya secara historis (sejak pertengahan 90-an) selalu tidak di-subdirektori menjadi subdirektori. Jika semuanya dimasukkan ke dalam direktori tunggal (sebagaimana mestinya), isinya kemudian dapat dipindahkan ke tempat yang tepat dengan mv, maka Anda dapat menghapus direktori ekstra yang berlebihan. Dua langkah tambahan ya, tapi itu mengalahkan membersihkan kekacauan dari file tar yang salah dibuat.
TED
6
But some punk projects put everything at the root :'-(Dan beberapa proyek punk memasukkan semuanya ke dalam folder yang sama sekali tidak perlu, mengingat bahwa mereka sudah meletakkan semuanya di dalam arsip yang terlampir, sehingga ketika Anda mengunduh dan meng-unzip ke foldernya sendiri seperti yang dilakukan oleh pengguna pintar, Anda berakhir dengan semua konten mengubur lapisan lain ke bawah. ;-)
Mason Wheeler
2
@MasonWheeler Ada semacam "standar de-facto" untuk arsip tar untuk memiliki semuanya dalam satu folder di dalamnya.
glglgl

Jawaban:

30

patool menangani berbagai jenis arsip dan membuat subdirektori seandainya arsip tersebut berisi banyak file untuk mencegah kekacauan direktori kerja dengan file yang diekstrak.

Ekstrak arsip

patool extract archive.tar

Untuk mendapatkan daftar format yang didukung, gunakan patool formats.

Marco
sumber
FYI: Ditemukan di sourceforge.net/projects/patool . Ini adalah rpm dan saya biasa alienmengubahnya menjadi deb untuk Ubuntu.
Joe
patoolharus dalam repo untuk Debian dan Ubuntu jika Anda menjalankan versi saat ini.
Marco
12

Anda bisa melakukan sesuatu seperti

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

untuk melihat entri tingkat atas apa yang dimiliki tar; pipa untuk wc -lmemeriksa apakah ada lebih dari satu. Perhatikan bahwa ada beberapa kasus di mana ini akan gagal, misalnya jika tar berisi path file dari form somedir/whateverdan juga ./somedir/whatever(atau sesuatu yang lebih gila); ini seharusnya tidak biasa.

Ini akan membaca seluruh file tar sebelum mengeluarkan apa pun, karena itu sort, meskipun itu harus lebih cepat daripada benar-benar mengekstraksi karena itu hanya satu baca berurutan dan dapat melewati file besar.

Jika Anda melakukan ini secara interaktif dan file mungkin besar, Anda dapat mengubah sort -uke uniqdan Control+ Cjika mencetak lebih dari satu hal.

Dougal
sumber
2
sort | uniqdapat disingkat menjadi sort -u.
Marco
4
kecuali jika Anda ingin melakukanuniq -c
cas
7

Anda dapat melakukan:

pax <some.tar

... untuk membuat daftar isi suatu tarfile.

jika Anda ingin tahu berapa banyak level kedalamannya, Anda dapat melakukannya:

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

Anda dapat secara eksplisit melarang ledakan ekstraksi dengan:

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

Ini harus melakukan apa yang Anda inginkan. Saya yakin seseorang dapat memperbaikinya.Dalam contoh ini saya menganggap arsip tar terkompresi gzip karena ini adalah yang paling umum.

Anda ingin arsip di mana tidak ada saudara kandung node di pohon direktori level root.

Setiap entri dalam daftar konten tar harus dimulai dengan pola yang sama. Pola ini adalah jalur direktori dasar yang harus dibagi oleh semua entri dalam arsip. Jika ada dua entri yang tidak dimulai dengan pola yang sama maka mereka adalah saudara kandung.

Baris pertama dalam daftar konten tar akan memberi Anda pola minimal yang perlu Anda periksa. Ini BASEPATH.

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

Kemudian untuk menguji untuk tarball peledak Anda perlu memeriksa apakah setiap baris dari daftar isi tar tidak dimulai dengan BasePath.

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

Ubah ini menjadi fungsi shell:

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

Dari sini Anda dapat menulis fungsi ekstraksi arsip tar aman.

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 $?
}
Noah Spurrier
sumber