正常に実行される(つまり、_data.tar
ファイルを生成する)bashスクリプトに次の非常に単純な行がありますが、しない--exclude
オプションで除外するように指示されたサブディレクトリを除外します。
/bin/tar -cf /home/_data.tar --exclude='/data/sub1/*' --exclude='/data/sub2/*' --exclude='/data/sub3/*' --exclude='/data/sub4/*' --exclude='/data/sub5/*' /data
代わりに、除外したいサブディレクトリ内のファイルを含む、/ dataの下のすべてを含む_data.tar
ファイルを生成します。
なぜか?そしてこれを修正するには?
更新以下の最初の回答で提供されたリンクに基づいて、観察結果を実装しました(最上位のディレクトリが最初、最後の除外の後に空白はありません)。
/bin/tar -cf /home/_data.tar /data --exclude='/data/sub1/*' --exclude='/data/sub2/*' --exclude='/data/sub3/*' --exclude='/data/sub4/*' --exclude='/data/sub5/*'
しかし、それは役に立ちませんでした。すべての「除外された」サブディレクトリは、結果の_data.tar
ファイルに存在します。
これは不可解です。これが現在のtar(GNU tar 1.23、CentOS 6.2、Linux 2.6.32)のバグなのか、空白やその他の見落としがちな入力ミスに対するtarの「極端な感度」なのかは、このバグだと思います。今のところ。
これは恐ろしいことです:以下で提案された洞察を試してみました(末尾の/*
はありません)が、それでも本番スクリプトでは機能しません。
/bin/tar -cf /home/_data.tar /data --exclude='/data/sub1' --exclude='/data/sub2' --exclude='/data/sub3' --exclude='/data/sub4'
引用符と1の代わりに2つのスペースを除いて、私が試したものと@Richard Perrinが試したものとの間に違いはありません。これを試すつもりです(バックアップされるディレクトリとして毎晩スクリプトが実行されるのを待つ必要があります)アップは巨大です)と報告します。
/bin/tar -cf /home/_data.tar /data --exclude=/data/sub1 --exclude=/data/sub2 --exclude=/data/sub3 --exclude=/data/sub4
これらのtar --exclude
のすべての感度はtarではなく、私の環境内の何かであると私は考え始めていますが、それは何でしょうか?
動作しました!試行された最後のバリエーション(--exclude
s間のダブルスペースの代わりに単一引用符とシングルスペースなし)がテストされ、動作しました。奇妙だが受け入れる。
nbelievable!古いバージョンのtar
(1.15.1)は、トップレベルのディレクトリがlastである場合にのみ除外されることがコマンドラインで判明しました。これは、バージョン1.23で必要な方法とは正反対です。ご参考までに。
ディレクトリ全体を除外する場合、パターンはそのディレクトリ内のファイルではなく、そのディレクトリと一致する必要があります。使用する --exclude=/data/sub1
の代わりに --exclude='/data/sub1/*'
パターンを引用してシェル拡張から保護するように注意してください。
最後の呼び出しに問題があるこの例を参照してください。
$ for i in 0 1 2; do mkdir -p /tmp/data/sub$i; echo foo > /tmp/data/sub$i/foo; done
$ find /tmp/data
/tmp/data
/tmp/data/sub2
/tmp/data/sub2/foo
/tmp/data/sub0
/tmp/data/sub0/foo
/tmp/data/sub1
/tmp/data/sub1/foo
$ tar -zvcf /tmp/_data.tar /tmp/data --exclude='/tmp/data/sub[1-2]'
tar: Removing leading `/' from member names
/tmp/data/
/tmp/data/sub0/
/tmp/data/sub0/foo
$ tar -zvcf /tmp/_data.tar /tmp/data --exclude=/tmp/data/sub[1-2]
tar: Removing leading `/' from member names
/tmp/data/
/tmp/data/sub0/
/tmp/data/sub0/foo
$ echo tar -zvcf /tmp/_data.tar /tmp/data --exclude=/tmp/data/sub[1-2]
tar -zvcf /tmp/_data.tar /tmp/data --exclude=/tmp/data/sub[1-2]
$ tar -zvcf /tmp/_data.tar /tmp/data --exclude /tmp/data/sub[1-2]
tar: Removing leading `/' from member names
/tmp/data/
/tmp/data/sub2/
/tmp/data/sub2/foo
/tmp/data/sub0/
/tmp/data/sub0/foo
/tmp/data/sub2/
tar: Removing leading `/' from hard link targets
/tmp/data/sub2/foo
$ echo tar -zvcf /tmp/_data.tar /tmp/data --exclude /tmp/data/sub[1-2]
tar -zvcf /tmp/_data.tar /tmp/data --exclude /tmp/data/sub1 /tmp/data/sub2
お使いのバージョンのtar
では、--exclude
オプションは、tar
コマンドの先頭に配置する必要があります。
参照: https://stackoverflow.com/q/984204
tar --exclude='./folder' --exclude='./upload/folder2' \
-zcvf /backup/filename.tgz .
参照: http://mandrivausers.org/index.php?/topic/8585-multiple-exclude-in-tar/
tar --exclude=<first> --exclude=<second> -cjf backupfile.bz2 /home/*
代替:
EXCLD='first second third'
tar -X <(for i in ${EXCLD}; do echo $i; done) -cjf backupfile.bz2 /home/*
さらに別のtar
コマンドのヒントは here からです:
tar cvfz myproject.tgz --exclude='path/dir_to_exclude1' \
--exclude='path/dir_to_exclude2' myproject
複数のファイルを除外するには、
--exclude=/data/{sub1,sub2,sub3,sub4}
これはいくつかのコードと頭痛を節約します。これは、あらゆる種類のプログラム/オプション向けのグローバルなソリューションです。選択に親ディレクトリ(この場合はデータ)も含める場合は、末尾にコンマを含める必要があります。例えば。:
umount /data/{sub1,sub2,}
このリンクは役に立つかもしれません。 http://answers.google.com/answers/threadview/id/739467.html
機能していない回線とリンクのいくつかのヒントの間の2つの直接的な違い:
--exclude
の後にスペースを入れることはできません。私はMacを使用していますが、最上位のフォルダーが最後の引数でない限り、excludesが機能していませんでした。
作業コマンドの例:
tar czvf tar.tgz --exclude='Music' dir
ご参考までに:
$: tar --version
bsdtar 2.8.3 - libarchive 2.8.3
おそらく、別のオプションでコマンドを試すことができます。
--wildcards
そして、それが意図したとおりに実行されているかどうかを確認します。
回避策として、find ... -Prune
とtar
の組み合わせを使用して、指定したディレクトリを除外することができます。
Mac OS Xでは、GNU tar
の--exclude
オプションが正常に機能するようです。
次のテストケースでは、ディレクトリ/private/var/log/asl
および/private/var/log/DiagnosticMessages
を/private/var/log
ディレクトリの圧縮アーカイブから除外します。
# all successfully tested in Bash Shell on Mac OS X (using gnutar and gfind)
# Sudo port install findutils # for gfind from MacPorts
Sudo gnutar -czf ~/Desktop/varlog.tar.gz /private/var/log --exclude "/private/var/log/asl" --exclude "/private/var/log/DiagnosticMessages"
Sudo gnutar -czf ~/Desktop/varlog.tar.gz --exclude "/private/var/log/asl" --exclude "/private/var/log/DiagnosticMessages" /private/var/log
set -f # disable file name globbing
Sudo gnutar -czf ~/Desktop/varlog.tar.gz --exclude "/private/var/log/asl" --exclude "/private/var/log/Diagnostic*" /private/var/log
# combining GNU find and tar (on Mac OS X)
Sudo gfind /private/var/log -xdev -type d \( -name "asl" -o -name "DiagnosticMessages" \) -Prune -o -print0 |
Sudo gnutar --null --no-recursion -czf ~/Desktop/varlog.tar.gz --files-from -
# exclude even more dirs
Sudo gfind /private/var/log -xdev -type d \( -name "asl" -o -name "[Dacfks]*" \) -Prune -o -print0 |
Sudo gnutar --null --no-recursion -czf ~/Desktop/varlog.tar.gz --files-from -
# testing the compressed archive
gnutar -C ~/Desktop -xzf ~/Desktop/varlog.tar.gz
Sudo gfind /private/var/log ~/Desktop/private \( -iname DiagnosticMessages -or -iname asl \)
Sudo rm -rf ~/Desktop/varlog.tar.gz ~/Desktop/private
私の場合、別の理由で除外されませんでした。
絶対パスと相対パス。
除外とディレクトリの両方で同じパス形式を使用する必要があります(つまり、両方が完全パス、または両方が相対パス)
例:
tar -cvf ctms-db-sync.tar --exclude='/home/mine/tmp/ctms-db-sync/sql' ctms-db-sync
ターゲットが相対パスを使用するため、excludeはフルパスを使用するため、これは機能しません
tar -cvf ctms-db-sync.tar --exclude='/home/mine/tmp/ctms-db-sync/sql' /home/mine/tmp/ctms-db-sync
両方ともフルパスを使用するため、これは機能します
tar -cvf ctms-db-sync.tar --exclude='ctms-db-sync/sql' ctms-db-sync
どちらも相対パスを使用するため、これは機能します
の代わりに --exclude=
使用する -X
テキストファイル付き:
http://www.cyberciti.biz/faq/exclude-certain-files-when-creating-a-tarball-using-tar-command/
絶対パスではなく相対パスをアーカイブしたくないとします。 「/ tmp/data」の代わりに「data」。絶対パスを除外するには、使用するtar実装(gnu tarとbsd tar)に基づいてtar引数が異なります。
$ for i in 0 1 2; do
for j in 0 1 2; do
mkdir -p /tmp/data/sub$i/sub$j
echo foo > /tmp/data/sub$i/sub$j/foo
done
done
$ find /tmp/data/
/tmp/data/
/tmp/data/sub2
/tmp/data/sub2/sub2
/tmp/data/sub2/sub2/foo
/tmp/data/sub2/sub1
/tmp/data/sub2/sub1/foo
/tmp/data/sub2/sub0
/tmp/data/sub2/sub0/foo
/tmp/data/sub1
/tmp/data/sub1/sub2
/tmp/data/sub1/sub2/foo
/tmp/data/sub1/sub1
/tmp/data/sub1/sub1/foo
/tmp/data/sub1/sub0
/tmp/data/sub1/sub0/foo
/tmp/data/sub0
/tmp/data/sub0/sub2
/tmp/data/sub0/sub2/foo
/tmp/data/sub0/sub1
/tmp/data/sub0/sub1/foo
/tmp/data/sub0/sub0
/tmp/data/sub0/sub0/foo
$ cd /tmp/data; tar -zvcf /tmp/_data.tar --exclude './sub[1-2]'
./
./sub0/
./sub0/sub2/
./sub0/sub2/foo
./sub0/sub1/
./sub0/sub1/foo
./sub0/sub0/
./sub0/sub0/foo
# ATTENTION: bsdtar's behaviour differs from traditional tar (without a leading '^')!
$ cd /tmp/data; bsdtar -zvcf /tmp/_data.tar --exclude './sub[1-2]' .
a .
a ./sub0
a ./sub0/sub0
a ./sub0/sub0/foo
# FIX: Use a regex by adding a leading '^' will cause bsdtar to match only parent files and folders.
$ cd /tmp/data; bsdtar -zvcf /tmp/_data.tar --exclude '^./sub[1-2]' .
# ALTERNATIVE: bsdtar -C /tmp/data -zvcf /tmp/_data.tar --exclude '^./sub[1-2]' .
a .
a ./sub0
a ./sub0/sub2
a ./sub0/sub1
a ./sub0/sub0
a ./sub0/sub0/foo
a ./sub0/sub1/foo
a ./sub0/sub2/foo
たった今tar(GNU tar)1.29で検出されました
この呼び出しは、-exclude-fromで指定されたアーカイブファイルから除外しません。
/bin/tar --files-from ${datafile} --exclude-from ${excludefile} -jcf ${backupfile}
この呼び出しは正しく機能します。
/bin/tar --exclude-from ${excludefile} --files-from ${datafile} -jcf ${backupfile}
パラメータの順序は重要です!