Як безпечно знімати знімок, не забруднюючи поточний каталог у випадку tarbomb?


33

Солідні проекти звільнити архіви дьогтю, що містять один каталог, наприклад , zyrgus-3.18.tar.gzмістить zyrgus-3.18папку , яка , в свою чергу , містить src, build, distі т.д.

Але деякі панк-проекти прикладають все до кореня: '- (Це призводить до тотального безладу, коли не потрібно виконувати функції. Створення папки кожен раз вручну - це біль і непотрібне більшу частину часу.

  • Чи існує надшвидкий спосіб визначити, чи файл .tar або .tar.gz містить у своєму корені більше однієї каталогу? Навіть для великого архіву.
  • Або ще краще, чи є інструмент, який у таких випадках створив би каталог (ім’я архіву без розширення) і вклав би все всередину?


2
Я думаю, що зламана упаковка вартує повідомлення про помилку автору пакета.

14
Я історично (з середини 90-х) просто завжди перетворювався на підкаталог. Якщо його все помістити в єдиний каталог (як і належить), його вміст можна потім перенести в потрібне місце за допомогою mv, тоді ви можете видалити зайвий додатковий каталог. Два додаткові кроки, так, але це прибирання безладу від неправильно зробленого файлу з дьогтем.
ТЕД

6
But some punk projects put everything at the root :'-(А деякі панк-проекти ставлять все в папку абсолютно непотрібно, враховуючи, що вони вже поміщають все у доданий архів, так що коли ви завантажуєте та розпаковуєте його у власну папку, як це робив би будь-який розумний користувач, ви закінчуєте всі вміст закопаний ще один шар вниз. ;-)
Мейсон Уілер

2
@MasonWheeler Існує свого роду "фактичний стандарт" для архівів смоли, щоб все було в одній папці всередині.
glglgl

Відповіді:


30

patool обробляє різні види архівів і створює підкаталог у випадку, якщо архів містить декілька файлів, щоб запобігти захаращенню робочого каталогу вилученими файлами.

Витяг архіву

patool extract archive.tar

Щоб отримати список підтримуваних форматів, використовуйте patool formats.


FYI: Знайдено на сайті sourceforge.net/projects/patool . Це обороти в хвилину, і я використовував alienдля перетворення його в деб для Ubuntu.
Джо

patoolмає бути в репостах для Debian і Ubuntu, якщо ви використовуєте поточну версію.
Марко

12

Ви могли зробити щось подібне

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

щоб побачити, які записи в найвищому рівні має тар; трубу, щоб wc -lперевірити, чи є більше однієї. Зауважте, що є кілька випадків, коли це не вдасться, наприклад, якщо tar містить шляхи до форми somedir/whateverта також ./somedir/whatever(або щось більш божевільне); це, однак, має бути нечасто.

Це прочитає весь файл tar, перш ніж виводити що-небудь, через що sort, хоча це має бути швидше, ніж фактично вилучення, оскільки це лише одне послідовне читання, і він може пропускати великі файли.

Якщо ви робите це інтерактивно, і файл може бути великим, ви можете перейти sort -uдо uniqта Control+, Cякщо він виводить більше ніж одне.


2
sort | uniqможна скоротити до sort -u.
Марко

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

Це має робити те, що ви хочете. Я впевнений, що хтось може це покращити. У цих прикладах я припускаю, що стислий архів gzip tar, оскільки це найпоширеніший.

Ви хочете отримати архів, де в дереві каталогів кореневого рівня немає вузлів зближення.

Кожен запис у списку вмісту дьогтю повинен починатися з одного шаблону. Цей візерунок є базовим шляхом до каталогу, яким мають бути спільні всі записи в архіві. Якщо будь-які два записи не починаються з однакового шаблону, то вони є братами і сестрами.

Перший рядок у списку вмісту дьогтю дасть вам мінімальну схему, на яку потрібно перевірити. Це БАЗЕПАТ.

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

Потім для перевірки на вибухонебезпечні кульки потрібно перевірити, чи не починається якийсь рядок списку вмісту дьогтю з 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 $?
}

Звідси ви можете написати безпечну функцію вилучення архіву дьогтю.

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 $?
}

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.