はじめまして。
インフラを担当してますmatsBです。
とても限定的な話ですが、最近シンボリックリンクに興味を持ったので
その話をしたいと思います。
ディレクトリのシンボリックリンクを張ったら、プログラム内で相対パスを使うのは
"やってはいけない事"ってのは有名な話です。
"やってはいけない事"の理由は簡単で、シンボリックリンク内のディレクトリで
相対パスを使うとリンク元のディレクトリを参照するから。
ですね。
今回は改めて、
なんでリンク元のディレクトリを参照するか
を解説したいと思います。
言葉で説明すると長くなってしまうので、実際にやってみるのが早いですね。
ってことで、/home/user の配下にAとBのディレクトリを用意して
Bの1ディレクトリをAのシンボリックリンクにして
シンボリックリンク内で相対パスを実行して
"やってはいけない事"を実際に再現してみます。
AとBに同じファイル名で別内容のファイルを用意して、Aディレクトリにシェルを追加。
[user@localhost ~]$ cat /home/user/A/lib/test.txt A.txt [user@localhost ~]$ cat /home/user/B/lib/test.txt B.txt [user@localhost ~]$ cat /home/user/A/dir/test.sh #! /bin/bash /bin/cat ../lib/test.txt
BにAのシェルが置いてあるディレクトリのシンボリックリンクを張る。
[user@localhost ~]$ ln -s /home/user/A/dir /home/user/B/dir [user@localhost ~]$ ls -l /home/user/B/ 合計 0 lrwxrwxrwx 1 user user 16 8月 5 13:15 dir -> /home/user/A/dir drwxr-xr-x 2 user user 21 8月 5 14:33 lib
Bの方でシェルを実行。
[user@localhost ~]$ cd /home/user/B/dir/ [user@localhost dir]$ ./test.sh A.txt [user@localhost dir]$
とまぁ、Bディレクトリで../を実行しているのにリンク元のAディレクトリを参照してますね。
これは、catコマンドの中でgetcwdを使っているが、getcwd はinode番号を元に
親ディレクトリをたどってファイルパス名の値を返すからみたいです。
ウィキペディアからの引用ですが。
inode - Wikipedia
オペレーティングシステムは一度ファイル名を inode番号に変換すると、ファイル名の方を忘れてしまう。従って、getcwd() や getwd() といったライブラリ関数は "." ディレクトリに対応する inode 番号からその親ディレクトリを捜し、最終的に "/" ディレクトリまでたどることでフルパス名を得ている。
ってことで、、、
じゃあ実際にinode番号を確認していくと
[user@localhost ~]$ ls -lai [AB]/dir/ A/dir/: 合計 4 1610961388 drwxr-xr-x 2 user user 20 8月 5 17:20 . 537080780 drwxr-xr-x 4 user user 26 8月 5 17:20 ... 1610961394 -rwxr--r-- 1 user user 39 8月 5 17:20 test.sh B/dir/: 合計 4 1610961388 drwxr-xr-x 2 user user 20 8月 5 17:20 . 537080780 drwxr-xr-x 4 user user 26 8月 5 17:20 .. 1610961394 -rwxr--r-- 1 user user 39 8月 5 17:20 test.sh
A/dir/もB/dir/も".."のinode番号は「537080780」ですね。
ではinode番号「537080780」はどこのことなのか見てみると。
[user@localhost ~]$ ls -lai [AB] A: 合計 4 537080780 drwxr-xr-x 4 user user 26 8月 5 17:20 . 537080781 drwx------ 7 user user 4096 8月 5 17:20 .. 1610961388 drwxr-xr-x 2 user user 20 8月 5 17:20 dir 864335 drwxr-xr-x 2 user user 21 8月 5 14:33 lib B: 合計 4 1075097284 drwxr-xr-x 3 user user 26 8月 5 14:40 . 537080781 drwx------ 7 user user 4096 8月 5 17:20 .. 1075097285 lrwxrwxrwx 1 user user 16 8月 5 14:40 dir -> /home/user/A/dir 1610961389 drwxr-xr-x 2 user user 21 8月 5 14:33 lib
inode番号「537080780」はAの"."と同じでした。
って事はinode番号「537080780」とはAディレクトリの事を指しています。
つまり、B/dir/内で".."を指定するとAディレクトリを指すことになります。
まぁ当たり前といえば、当たり前の話ですね。
シンボリックリンクって使ってはいたけど、意外とどんな動きなのかを
調べたりする機会がなかったりします。
凄く限定的な情報ですが、この情報をどこかで活用する機会があれば
いいなと思っています。