tarで所有者(ユーザーID/グループID)が変わってしまう時は

概要

別のマシンで作ったtarアーカイブを展開すると、ユーザー名やグループ名は合っているけど、uid/gidが変わってしまうことがあります。

マシンAで下のようにtarアーカイブを作成して

$ ls -l myfile.txt 
-rw-rw-r-- 1 hoge hoge 5  8月 15 21:26 myfile.txt
$ ls -ln myfile.txt 
-rw-rw-r-- 1 2000 2000 5  8月 15 21:26 myfile.txt
$ tar cf test.tar myfile.txt 

作成したtarアーカイブを別のマシンBで展開すると

$ sudo tar xf test.tar 
$ ls -l myfile.txt 
-rw-rw-r-- 1 hoge hoge 5  8月 15 21:26 myfile.txt
$ ls -ln myfile.txt 
-rw-rw-r-- 1 3000 3000 5  8月 15 21:26 myfile.txt

となります。

それぞれを比べると、ユーザー名とグループ名は同じですがuid/gidが異なっています。

ユーザー/グループ名
マシンA) -rw-rw-r-- 1 hoge hoge 5  8月 15 21:26 myfile.txt
マシンB) -rw-rw-r-- 1 hoge hoge 5  8月 15 21:26 myfile.txt

uid/gid
マシンA) -rw-rw-r-- 1 2000 2000 5  8月 15 21:26 myfile.txt
マシンB) -rw-rw-r-- 1 3000 3000 5  8月 15 21:26 myfile.txt


解決方法

こんな時は、アーカイブを展開するときに --numeric-ownerオプションを指定すれば解決します。

$ tar xf test.tar --numeric-owner 

アーカイブを作成するときに--numeric-ownerオプションを指定しても大丈夫です。ただし、作成するときに指定すると、このあとで説明するようにユーザー名とグループ名がアーカイブに格納されないので注意してください。

$ tar cf test.tar myfile.txt --numeric-owner 


なにが起きているのか

これは、tarコマンドがスーパーユーザー権限でアーカイブを展開するときは、一致するユーザー名やグループ名があるとuid/gidよりも優先するからです。

tarはアーカイブを作成するときにファイルのユーザー/グループ名とuid/gidの両方をアーカイブに格納しています。

スーパーユーザー権限でアーカイブを展開すると、まずアーカイブに格納されているユーザー名と同じユーザー名が展開しているマシンにないか探します。見つかると、そのユーザーのuidをファイルのuidにします。見つからなければ、アーカイブに格納されているuidをファイルのuidにします。(グループの場合も同じ仕組みです)

tarアーカイブに格納されたユーザー名をもとにuidを調べて、展開したファイルのuidが決定されます

このために、同じユーザー/グループ名が異なるuid/gidを持つマシン間でtarアーカイブを作成・展開するとuid/gidが変わってしまうという現象がおきます。

多くの場合は、元のマシンでhogeさんが所有者だったファイルは展開先のマシンでもhogeさんが所有者になるので都合がいいのですが、時として問題が発生します。例えば、作業用マシンにstorageをmountしてtarを展開したりすると、作業用マシンの設定の影響をうけてuid/gidが変わってしまう場合があります。

こんな場合は、--numeric-ownerオプションを指定します。アーカイブを展開するときに、このオプションが指定されていると同じユーザー名を探さないでアーカイブに格納されているuid/gidを使います。


補足情報


なぜ、作成時にオプション指定でも大丈夫なのか?

--numeric-ownerオプションをつけて作成したtarアーカイブには、ユーザー/グループ名が格納されていないためです。

下は--numeric-ownerオプションをつけた場合とつけなかった場合のtarアーカイブを比較したものです。オプションをつけるとユーザー名とグループ名がなくなっているのがわかります。(下のdump部分には含まれていませんが、uid/gidは別の場所に格納されています)

 17c17
 < 000100 00 75 73 74 61 72 20 20 00 68 6f 67 65 00 00 00  >.ustar  .hoge...< オプション無し
 ---
 > 000100 00 75 73 74 61 72 20 20 00 00 00 00 00 00 00 00  >.ustar  ........< オプション有り
19c19 < 000120 00 00 00 00 00 00 00 00 00 68 6f 67 65 00 00 00 >.........hoge...< オプション無し
--- > 000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >................< オプション有り

このように、ユーザー/グループ名自体が格納されていないため、スーパーユーザー権限でアーカイブを展開しても一致するユーザー/グループ名のuid/gidで置き換えるということがありません。

格納されているuid/gidを見るには?

-t, --listでアーカイブの内容一覧を表示するときに、--numeric-ownerオプションを指定すればユーザー/グループ名の代わりにuid/gidが表示されます。

--numeric-ownerオプションを指定すると下のようにuid/gidが表示されます。

$ tar tvf test.tar --numeric-owner
-rw-rw-r-- 2000/2000         5 2021-08-15 21:26 myfile.txt

オプションを指定しないと下のように名前で表示されます。

$ tar tvf test.tar
-rw-rw-r-- hoge/hoge         5 2021-08-15 21:26 myfile.txt

オプションを指定して作成したアーカイブを一覧すると?

--numeric-ownerオプションを指定して作成したアーカイブには、ユーザー/グループ名が格納されていません。このため、内容一覧を表示すると当然uid/gidが表示されます。

$ tar tvf with-option.tar
-rw-rw-r-- 2000/2000         5 2021-08-15 21:26 myfile.txt




No Comment