0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

シンボリックリンクの生成で相対パスを指定すると危険だった話

Last updated at Posted at 2020-08-03

08/04追記
コメントにて補足や訂正を頂いたので、適宜修正をしていきます。

はじめに

シェルコマンドを学習しているとき、シンボリックリンクに関して沼にハマってしまったので、備忘録を残します。
これがベストプラクティスかどうかは知らないが、シンボリックリンクの生成はなるべく絶対パスを使おう。

これは時と場合によるので、ベストプラクティスとは言えません。
リンク元のファイル・リンクをまとめて管理したい場合、設置場所変更に弱くなるためです。
※Webページのリンク ( ハイパーリファレンス ) を絶対URLで書くか、相対URLで書くかと同じ問題
@angel_p_57

シンボリックリンクとは

シンボリックリンクとは、オペレーティングシステム(OS)のファイルシステムの機能の一つで、特定のファイルやディレクトリを指し示す別のファイルを作成し、それを通じて本体を参照できるようにする仕組み。
IT用語辞典 e-Words

Linuxにおけるシンボリックリンクは、Windowsでいうところのショートカットのようなものだと認識しています。

目的は似ていますが、実態は大分違います。加えて、Windowsにも ( リパース・ポイントという機能を利用した ) シンボリックリンクが存在します。
ショートカットは、指定のファイルをアプリで開くための情報を持ったランチャーに過ぎませんが、シンボリックリンクは指定のファイルの代替として使えるファイルです。
@angel_p_57

シンボリックリンクの作成

シンボリックリンクの作成に用いるコマンドは以下です。
hoge.jpgは任意のファイル名、fugaは任意のディレクトリ名です。
ここではhoge.jpgというファイルのシンボリックリンクを、fugaディレクトリに生成します。


$ ln -s hoge.jpg fuga

補足:このケースでは『既にfugaディレクトリが存在していれば』意図どおりに正常に実行されます。
fugaディレクトリがなければ、同一ディレクトリにfugaという名前のシンボリックリンクが生成されてしまいます。

$ ln -s hoge.jpg fuga/ とすれば、ディレクトリが存在していれば実行するコマンドになります。
(頂いたコメントを参考にしました)

やりたいこと

~/Picture/konosuba.jpg のシンボリックリンクを、
~/Picture/foobar に生成したい。

やってみたこと

相対パスで指定した場合(failed)

カレントディレクトリが ~/Pictureだとする。


~/Picture $ ln -s konosuba.jpg foobar

foobarディレクトリに konosuba.jpgは いちおう生成されるが、
先にいっておくと、これは間違い。

カレントディレクトリ内に存在する konosuba.jpgのシンボリックリンクが、相対パスとして指定したfoobarフォルダ内に生成される・・・というわけではない。

foobarディレクトリに生成されたシンボリックリンク konosuba.jpgは、
自身から見た相対パス konosuba.jpg つまり同ディレクトリ内のkonosuba.jpgを参照しにいく、と考えよう。

つまり、自身を参照するシンボリックリンクという謎のファイルを生成してしまう。

(これは、シェルコマンドの第一引数である"konosuba.jpg"を、シンボリックリンク自身の位置を基準とした相対パスとして読み取ってしまうため)

相対パスで指定した場合(successed)

カレントディレクトリが ~/Pictureだとする。


~/Picture $ ln -s ../konosuba1.jpg foobar

foobarディレクトリに konosuba.jpgが生成される。
こいつは正解。
foobar ディレクトリに生成されたシンボリックリンクkonosuba.jpg は、
自身の位置から見て "../konosuba1.jpg"を参照するリンクとして生成される。

慣れると問題ないのかもしれないが、正直僕にはややこしく感じました。

その場合は、-r ( --relative ) というオプションを使います。相対位置はコマンドが自動的に判断してくれますから。
ln -s hoge.jpg fuga/ だと、作成されるシンボリックリンク fuga/hoge.jpg は循環参照を起こして役に立ちませんが、ln -s -r hoge.jpg fuga/ とすれば、fuga/hoge.jpg -> ../hoge.jpg という適切なリンクを作成してくれます。
@angel_p_57

絶対パスで書く


$ ln -s ~/Picture/konosuba.jpg ~/Picture/foobar

絶対パスなら参照元が意図と異なるリスクをぐっと減らせる。
ディレクトリ構造がややこしくなると、とんでもないことになりそうな気もするが、とりあえず間違えることはなくなるはずだ・・

おわりに

なんだかうまく書けた気がしないので、適宜変更を加えていこうと思う・・

参考文献

Linuxコマンドライン入門
Ubuntu Manuals

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?