Jak rozpakować bezpiecznie, bez zanieczyszczania bieżącego katalogu w przypadku tarbomb?


33

Projekty szanowanych zwolnić archiwa tar, które zawierają pojedynczy katalog, na przykład zyrgus-3.18.tar.gzzawiera zyrgus-3.18folder, który z kolei zawiera src, build, dist, itd.

Ale w niektórych projektach punkowych wszystko leży u podstaw: „(powoduje to całkowity bałagan podczas rozpakowywania. Ręczne tworzenie folderu za każdym razem jest uciążliwe i niepotrzebne przez większość czasu.

  • Czy istnieje superszybki sposób stwierdzenia, czy plik .tar lub .tar.gz zawiera więcej niż jeden katalog w katalogu głównym? Nawet dla dużego archiwum.
  • Lub jeszcze lepiej, czy istnieje narzędzie, które w takich przypadkach stworzyłoby katalog (nazwę archiwum bez rozszerzenia) i umieściłoby wszystko w środku?


2
Myślę, że zepsute opakowanie jest warte zgłoszenia błędu autorowi pakietu.

14
Historycznie (od połowy lat 90.) po prostu zawsze rozpakowywałem się w podkatalogu. Jeśli wszystko jest umieszczone w jednym katalogu (tak, jak powinno być), jego zawartość można następnie przenieść za pomocą mv we właściwe miejsce, a następnie można usunąć zbędny dodatkowy katalog. Dwa dodatkowe kroki tak, ale pokonuje usuwanie bałaganu z błędnie utworzonego pliku tar.
TED,

6
But some punk projects put everything at the root :'-(Niektóre projekty punkowe całkowicie niepotrzebnie umieszczają wszystko w folderze, biorąc pod uwagę, że umieszczają już wszystko w załączonym archiwum, więc kiedy pobierzesz i rozpakujesz go do własnego folderu, tak jak zrobiłby to każdy inteligentny użytkownik, skończysz z całą treść zakryła kolejną warstwę. ;-)
Mason Wheeler

2
@MasonWheeler Istnieje pewien „de facto standard” dla archiwów tar, aby mieć wszystko w jednym folderze.
glglgl,

Odpowiedzi:


30

patool obsługuje różnego rodzaju archiwa i tworzy podkatalog na wypadek, gdyby archiwum zawierało wiele plików, aby zapobiec zaśmiecaniu katalogu roboczego wyodrębnionymi plikami.

Wyodrębnij archiwum

patool extract archive.tar

Aby uzyskać listę obsługiwanych formatów, użyj patool formats.


FYI: Znaleziono go na sourceforge.net/projects/patool . Jest to rpm i kiedyś alienkonwertowałem go na deb dla Ubuntu.
Joe

patoolpowinien być w repozytoriach dla Debiana i Ubuntu, jeśli używasz aktualnej wersji.
Marco

12

Możesz zrobić coś takiego

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

aby zobaczyć, jakie wpisy najwyższego poziomu mają tar; potokuj, aby wc -lsprawdzić, czy jest więcej niż jeden. Zauważ, że jest kilka przypadków, w których to się nie powiedzie, np. Jeśli tar zawiera ścieżki plików formularza somedir/whateveri również ./somedir/whatever(lub coś bardziej szalonego); powinno to jednak być rzadkie.

Spowoduje to odczytanie całego pliku tar przed wypisaniem czegokolwiek, ponieważ sortpowinno to być szybsze niż rozpakowywanie, ponieważ jest to tylko jeden odczyt sekwencyjny i może pomijać duże pliki.

Jeśli robisz to interaktywnie, a plik może być duża, można zmienić sort -udo uniqi Control+ Cjeśli drukuje się więcej niż jedno.


2
sort | uniqmożna skrócić do sort -u.
Marco

4
chyba że chcesz to zrobićuniq -c
cas

7

możesz to zrobić:

pax <some.tar

... aby wyświetlić zawartość tarpliku.

jeśli chcesz wiedzieć, ile to poziomów, możesz zrobić:

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

możesz jawnie zabronić eksplozji podczas ekstrakcji za pomocą:

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

2

To powinno zrobić, co chcesz. Jestem pewien, że ktoś może to poprawić. W tych przykładach zakładam, że archiwum tar skompresowane gzip jest najczęstsze.

Chcesz archiwum, w którym nie ma węzłów rodzeństwa w drzewie katalogów na poziomie katalogu głównego.

Każdy wpis na liście zawartości tar musi zaczynać się od tego samego wzorca. Ten wzorzec jest ścieżką katalogu podstawowego, którą muszą udostępniać wszystkie wpisy w archiwum. Jeśli jakieś dwa wpisy nie zaczynają się od tego samego wzorca, są rodzeństwem.

Pierwszy wiersz na liście zawartości tar podaje minimalny wzorzec, który należy sprawdzić. To jest BASEPATH.

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

Następnie do testu dla tarballs wybuchem trzeba sprawdzić, czy każdy wiersz listy zawartości smoły nie zacząć od BasePath.

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

Zmień to w funkcję powłoki:

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

Stąd możesz napisać bezpieczną funkcję ekstrakcji archiwum 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 $?
}

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.