これはあなたが望むことをするはずです。誰かがそれを改善できると確信しています。これらの例では、最も一般的な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 $?
}