tarbombの場合に現在のディレクトリを汚染することなく、安全にuntarする方法は?


33

立派なプロジェクトは、例えば、単一のディレクトリが含まれているtarアーカイブを解放zyrgus-3.18.tar.gz含まれているzyrgus-3.18順番に入っているフォルダをsrcbuilddistなど、

しかし、いくつかのパンクのプロジェクトはルートにすべてをかける: ' - (この結果、総混乱。アーカイブ解除時に毎回手動でのフォルダを作成し、痛みであり、時間の不必要なほとんど。

  • .tarまたは.tar.gzファイルのルートに複数のディレクトリが含まれているかどうかを判断するための超高速の方法はありますか?大きなアーカイブでも。
  • または、さらに良いことに、そのような場合にディレクトリ(拡張子のないアーカイブの名前)を作成し、すべてを内部に配置するツールはありますか?


2
パッケージ作成者へのバグ報告に値する壊れたパッケージングだと思います。

14
私は歴史的に(90年代半ば以降)常にサブディレクトリに展開しました。すべてが単一のディレクトリに配置されている場合(必要に応じて)、その内容をmvを使用して適切な場所に移動してから、余分な余分なディレクトリを削除できます。余分な2つのステップはありますが、誤って作成されたtarファイルから混乱を一掃することに勝ります。
TED

6
But some punk projects put everything at the root :'-(そして、いくつかのパンクプロジェクトでは、すべてをフォルダ内に完全に不必要に配置します。これは、すべてを囲んでいるアーカイブ内に既に配置しているため、賢いユーザーが行うように、それを独自のフォルダにダウンロードして解凍すると、すべてのものになりますコンテンツは別のレイヤーを埋めました。;-)
メイソンウィーラー

2
@MasonWheeler tarアーカイブにすべてを1つのフォルダーに入れるための一種の「事実上の標準」があります。
glglgl

回答:


30

patoolはさまざまな種類のアーカイブを処理し、アーカイブに複数のファイルが含まれる場合にサブディレクトリを作成して、抽出されたファイルで作業ディレクトリが乱雑になるのを防ぎます。

アーカイブを抽出する

patool extract archive.tar

サポートされている形式のリストを取得するには、を使用しますpatool formats


参考:sourceforge.net/projects/patoolで見つけました。これはrpmでありalien、Ubuntuのdebに変換するために使用していました。
ジョー

patool現在のバージョンを実行している場合は、DebianおよびUbuntuのリポジトリにある必要があります。
マルコ

12

次のようなことができます

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

tarのトップレベルエントリを確認します。にパイプしてwc -l、複数あるかどうかを確認します。タールは、フォームのファイルパスが含まれている場合、これは例えば、失敗するいくつかの例があることに注意してくださいsomedir/whateverまた、および./somedir/whatever(または何かスゴが)。ただし、これはまれです。

これは、のために、何かを出力する前にtarファイル全体を読み取りますが、sort1回の順次読み取りであり、大きなファイルをスキップできるため、実際に抽出するよりも高速である必要があります。

あなたが対話的にこれをやっていると、ファイルが大きいかもしれない場合は、変更することができますsort -uuniqして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アーカイブを想定しています。

ルートレベルのディレクトリツリーに兄弟ノードがないアーカイブが必要な場合。

tarコンテンツリストのすべてのエントリは、同じパターンで始まる必要があります。このパターンは、アーカイブ内のすべてのエントリが共有する必要があるベースディレクトリパスです。2つのエントリが同じパターンで始まらない場合、それらは兄弟です。

tarコンテンツリストの最初の行は、確認する必要がある最小限のパターンを示します。これがBASEPATHです。

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

次に爆発的なtarball をテストするには、tarコンテンツリストのいずれかの行が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.