tarコマンドのバージョンによってシンボリックリンクの扱いが異なる件を調べてみた

# 概要

tarコマンドを利用し、とあるtar.gzファイルを展開したところLinuxの環境によってシンボリックリンクの扱いが異なっていましたので事象について内容をまとめてみました。

# 事象

まずはディレクトリ `bbb` を作成し、ディレクトリ内にファイル `ccc` を作成します。
ディレクトリ `bbb` はtarボール `archive.tar.gz` として作成します。

```
[root@LINUX test]# mkdir bbb
[root@LINUX test]# touch bbb/ccc
[root@LINUX test]# tar cvzf archive.tar.gz bbb
bbb/
bbb/ccc
[root@LINUX test]# ls -l
合計 8
-rw-r--r-- 1 root root  136 10月  9 15:02 2018 archive.tar.gz
drwxr-xr-x 2 root root 4096 10月  9 15:02 2018 bbb
```

ディレクトリ `bbb` を削除し、空のディレクトリ `aaa` を作成します。

```
[root@LINUX test]# rm -f -r bbb
[root@LINUX test]# mkdir aaa
[root@LINUX test]# ls -l
合計 8
drwxr-xr-x 2 root root 4096 10月  9 15:06 2018 aaa
-rw-r--r-- 1 root root  136 10月  9 15:02 2018 archive.tar.gz
```

空のディレクトリ `aaa` に対してシンボリックリンク `bbb` を作成します。

```
[root@TRHEL664 test]# ln -s aaa bbb
[root@TRHEL664 test]# ls -l
合計 8
drwxr-xr-x 2 root root 4096 10月  9 15:06 2018 aaa
-rw-r--r-- 1 root root  136 10月  9 15:02 2018 archive.tar.gz
lrwxrwxrwx 1 root root    3 10月  9 15:07 2018 bbb -> aaa
```

この状態で先ほど作成したtarボールを展開するとどうなるか見てみます。

```
[root@LINUX test]# tar xvzf archive.tar.gz
bbb/
bbb/ccc
[root@LINUX test]# ls -l
合計 8
drwxr-xr-x 2 root root 4096 10月  9 15:02 2018 aaa
-rw-r--r-- 1 root root  136 10月  9 15:02 2018 archive.tar.gz
lrwxrwxrwx 1 root root    3 10月  9 15:07 2018 bbb -> aaa
[root@LINUX test]# ls -l aaa
合計 0
-rw-r--r-- 1 root root 0 10月  9 15:02 2018 ccc
```

シンボリックリンク `bbb` はそのままで、ディレクトリの実体である `aaa` の中にファイル `ccc` が展開されています。

実はこれはtarコマンドのバージョンが `1.23` までの動作となります。
`1.24` 以降では次のようにシンボリックリンクの扱いが異なっています。

```
[root@LINUX test]# /usr/local/bin/tar --version
tar (GNU tar) 1.24
Copyright (C) 2010 Free Software Foundation, Inc.
使用許諾 GPLv3+: GNU GPL version 3 またはそれ以降 <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

[参考訳]
これはフリーソフトウェアです. 変更と再配布は自由です.
法律で認められる範囲で「無保証」です.

作者: John Gilmore, Jay Fenlason.
[root@LINUX test]# /usr/local/bin/tar xvzf archive.tar.gz
bbb/
bbb/ccc
[root@LINUX test]# ls -l
合計 12
drwxr-xr-x 2 root root 4096 10月  9 15:02 2018 aaa
-rw-r--r-- 1 root root  136 10月  9 15:02 2018 archive.tar.gz
drwxr-xr-x 2 root root 4096 10月  9 15:02 2018 bbb
```

tarコマンドのバージョンが `1.24` 以降だとシンボリックリンクは削除され、ディレクトリ `bbb` に置き換わってしまいます。
tarコマンドのバージョンによってシンボリックリンクの扱いが異なるため、注意が必要です。

# 対処方法

tarボールを作成するときにディレクトリを指定するのではなく、ファイルのパスを指定することで `1.24` 以降でもシンボリックリンクが置き換わることなくファイルを展開させることができます。

```
[root@LINUX test]# mkdir bbb
[root@LINUX test]# touch bbb/ccc
[root@LINUX test]# tar cvzf archive.tar.gz bbb/ccc
bbb/ccc
[root@LINUX test]# rm -f -r bbb
[root@LINUX test]# mkdir aaa
[root@LINUX test]# ln -s aaa bbb
[root@LINUX test]# ls -l
合計 8
drwxr-xr-x 2 root root 4096 10月  9 15:21 2018 aaa
-rw-r--r-- 1 root root  110 10月  9 15:21 2018 archive.tar.gz
lrwxrwxrwx 1 root root    3 10月  9 15:21 2018 bbb -> aaa
[root@LINUX test]# /usr/local/bin/tar xvzf archive.tar.gz
bbb/ccc
[root@LINUX test]# ls -l
合計 8
drwxr-xr-x 2 root root 4096 10月  9 15:22 2018 aaa
-rw-r--r-- 1 root root  110 10月  9 15:21 2018 archive.tar.gz
lrwxrwxrwx 1 root root    3 10月  9 15:21 2018 bbb -> aaa
[root@LINUX test]# ls -l aaa
合計 0
-rw-r--r-- 1 root root 0 10月  9 15:21 2018 ccc
```