find
の出力をパイプで接続すると、tar
各ファイルへの2つのリンクが結果のアーカイブに表示されます。tar
ディレクトリに直接適用する場合はそうではありません。重複リンクを避けることはできますか?
例は次のとおりです。
$ mkdir tmp
$ for i in {1..3}; do echo "$i" > "tmp/$i"; done
$ ls tmp
1 2 3
$ tar -cvvf tmp.tar tmp | sort
drwxr-xr-x usr/grp 0 2019-05-02 15:09 tmp/
-rw-r--r-- usr/grp 2 2019-05-02 15:09 tmp/1
-rw-r--r-- usr/grp 2 2019-05-02 15:09 tmp/2
-rw-r--r-- usr/grp 2 2019-05-02 15:09 tmp/3
$ find tmp | tar -T - -cvvf tmp.tar | sort
drwxr-xr-x usr/grp 0 2019-05-02 15:09 tmp/
hrw-r--r-- usr/grp 0 2019-05-02 15:09 tmp/1 link to tmp/1
hrw-r--r-- usr/grp 0 2019-05-02 15:09 tmp/2 link to tmp/2
hrw-r--r-- usr/grp 0 2019-05-02 15:09 tmp/3 link to tmp/3
-rw-r--r-- usr/grp 2 2019-05-02 15:09 tmp/1
-rw-r--r-- usr/grp 2 2019-05-02 15:09 tmp/2
-rw-r--r-- usr/grp 2 2019-05-02 15:09 tmp/3
これはGNU tar 1.26を使用して行われた。
答え1
SteelDriverが指摘したように、問題はtar
ディレクトリ内のファイルだけを受け取るのではなく、ディレクトリ自体も受け取ることです。デフォルトの動作はtar
ディレクトリを介して再帰するため、ディレクトリ内の各エントリは2番目に追加されます(一度は明示的にファイルを提供し、一度は明示的に提供されたディレクトリを介して再帰)。解決策は、(1)ディレクトリを提供しない、または(2)再帰を無効にすることです。
最初のものは次のとおりです。
$ find tmp -type f -print0 | sort -z | tar --null -T - -cvvf tmp.tar
-rw-r--r-- usr/grp 2 2019-05-02 17:06 tmp/1
-rw-r--r-- usr/grp 2 2019-05-02 17:06 tmp/2
-rw-r--r-- usr/grp 2 2019-05-02 17:06 tmp/3
2番目のケース(完全にネストされたディレクトリ構造を再現したいので必要です)は、単に再帰を無効にすることです。
$ find tmp -print0 | sort -z | tar --no-recursion --null -T - -cvvf tmp.tar
drwxr-xr-x usr/grp 0 2019-05-02 17:06 tmp/
-rw-r--r-- usr/grp 2 2019-05-02 17:06 tmp/1
-rw-r--r-- usr/grp 2 2019-05-02 17:06 tmp/2
-rw-r--r-- usr/grp 2 2019-05-02 17:06 tmp/3