Provided by: manpages-ja_0.5.0.0.20180315+dfsg-1_all
名前
symlink - シンボリックリンクの取り扱い
説明
シンボリックリンクは他のファイルへのポインターとして振る舞うファイルである。 その挙動を理 解するには、まずハードリンクがどのように機能するかを理解しておかなければならない。 あるファイルへのハードリンクは、 元々のファイルと区別することができない。 なぜなら、 ハー ドリンクは元々のファイル名の裏にあるオブジェクトへの参照だからである。 (より正確には、 あ るファイルへのハードリンクはそれぞれ同じ inode 番号 への参照である。 inode 番号は inode テーブルへのインデックスで、 inode テーブルはファイルシステム上のすべてのファイルについて のメタデータを保持している。 stat(2) 参照。) ファイルへの変更は、ファイルの参照に使用され た名前とは独立に行われる。 ハードリンクはディレクトリを参照することはできない (これはファ イルシステムツリー内でループが発生する可能性を防止するためであり、 ループが発生すると、 多 くのプログラムが混乱してしまうことだろう)。 また、 ハードリンクは異なるファイルシステム上 のファイルを参照することもできない (inode 番号はファイルシステムをまたがると一意ではないか らである)。 シンボリックリンクは特別な種類のファイルで、 ファイルの内容はそのリンクの参照先の別のファ イルのパス名を示す文字列である (シンボリックリンクの内容は readlink(2) を使って読むことが できる)。 言い換えると、 シンボリックリンクは別の名前へのポインターであり、 ファイルの裏に あるオブジェクトへのポインターではない。 この理由から、 シンボリックリンクではディレクトリ への参照やファイルシステム境界を越える参照を行うことができる。 シンボリックリンクが参照する先のパス名が存在しないといけないという要件はない。 存在しない パス名を参照するシンボリックリンクは「壊れた (dangling) リンク」と呼ばれる。 シンボリックリンクとその参照先のオブジェクトは一つのファイルシステムの名前空間内に共存する ので、 リンクそのものと参照先のオブジェクトの間で混乱が生じる可能性がある。 かなり昔からあ るシステムでは、 コマンドやシステムコールはいくらかアドホックな方法の独自のリンクの辿り方 の決まり事を採用している。 ここでは、 Linux や他のシステムで実装されている、 もっと広く使 われている方法のルールについて概要を説明する。 サイト固有のアプリケーションもこれらのルー ルに準拠し、 可能な限りユーザーインターフェースが一貫したものになるようにすることが重要で ある。 シンボリックリンクの所有権、アクセス許可、タイムスタンプ 既存のシンボリックリンクの所有者とグループは lchown(2) を使って変更することができる。 シン ボリックリンクの所有権が問題となる場面は、 スティッキービット (stat(2) 参照) がセットされ たディレクトリで、 そのリンクの削除や名前の変更を行おうとしている場合だけである。 シンボリックリンクの最終アクセス時刻と最終修正時刻は utimensat(2) や lutimes(3) で変更でき る。 Linux では、シンボリックリンクのアクセス許可 (permission) はどの操作でも使用されない。 ア クセス許可は常に 0777 (すべてのユーザーカテゴリーにおいて読み出し、書き込み、実行が可能) で、変更できない。 シンボリックリンクを参照するファイルディスクリプターを取得する open(2) に O_PATH と O_NOFOLLOW の両方のフラグを指定すると、ファイルディスクリプターが得ら れる。このファイルディスクリプターは fstatat(2), fchownat(2), fchmodat(2), linkat (2), readlinkat(2) などのシステムコールの dirfd 引き数として渡して、 (シンボリックリンクが参照 するファイルではなく) シンボリックリンク自身に対する操作を行うことができる。 デフォルトでは (すなわち AT_SYMLINK_FOLLOW フラグが指定されなかった場合)、 name_to_handle_at(2) がシンボリックリンクに適用された場合、 (シンボリックリンクが参照する ファイルではなく) シンボリックリンクへのハンドルが返される。 それ以降の open_by_handle_at(2) で O_PATH フラグを指定することで、 (シンボリックリンクが参照するファ イルではなく) シンボリックリンクに対するファイルディスクリプターを得ることができる。 繰り 返しになるが、 このファイルディスクリプターを上述のシステムコールで使用し、 シンボリックリ ンク自身に操作を行うことができる。 システムコールやコマンドによるシンボリックリンクの取り扱い シンボリックリンクは、 リンク自身に対する操作か、 リンクが参照するオブジェクトに対する操作 のいずれかとして扱われる。 後者の場合、 アプリケーションやシステムコールはリンクを辿る (follow)と呼ばれる。 シンボリックリンクは他のシンボリックリンクを参照することもできる。 こ の場合、 シンボリックリンクでないオブジェクトが見つかるか、 存在しないファイルを参照するシ ンボリックリンクが見つかるか、 ループが検出されるまで、 リンクの展開が行われる。 (ループの 検出は辿ることができるリンクの数に上限を設けることで行われる。 この上限を超過した場合はエ ラーとなる。) 3 つの領域に分けて議論する必要がある。以下の 3 つである。 1. システムコールのファイル名引き数としてシンボリックリンクが使用される場合。 2. ファイルツリーを辿っていないユーティリティーのコマンドライン引き数としてシンボリックリ ンクが指定される場合。 3. ファイルツリーを辿っているユーティリティーがシンボリックリンクを見つけた場合 (コマンド ラインで指定される場合もあれば、 ファイル階層を辿っている途中で遭遇する場合もある)。 システムコール 最初の領域は、システムコールのファイル名引き数としてシンボリックリンクが使用される場合であ る。 以下に述べる場合を除くと、 すべてのシステムコールはシンボリックリンクを辿る。 例えば、 afile という名前のファイルを指しているシンボリックリンク slink があったとすると、 システム コール open("slink" ...) はファイル afile を参照するファイルディスクリプターを返す。 リンクを辿らず、シンボリックリンク自身に対して操作を行うシステムコールもある。 このような システムコールとしては、 lchown(2), lgetxattr(2), llistxattr(2), lremovexattr(2), lsetxattr(2), lstat(2), readlink(2), rename(2), rmdir(2), unlink(2) がある。 他のいくつかのシステムコールは、指定された場合にのみシンボリックリンクを辿る。 これらのシ ステムコールとしては、 faccessat(2), fchownat(2), fstatat(2), linkat(2), name_to_handle_at(2), open(2), openat(2), open_by_handle_at(2), utimensat(2) がある。 詳細 はそれぞれのマニュアルページを参照してほしい。 remove(3) は unlink(2) の別名なので、 この ライブラリ関数もシンボリックリンクを辿らない。 rmdir(2) がシンボリックリンクに対して行われ た場合、その呼び出しはエラー ENOTDIR で失敗する。 link(2) については特別に議論が必要である。 POSIX.1-2001 では link(2) は oldpath がシンボ リックリンクであればこれを展開するように規定している。 しかしながら、 Linux はシンボリック リンクを展開しない。 (デフォルトでは Solaris も同じだが、 適切なコンパイラーオプションを指 定することで POSIX.1-2001 で規定された動作をさせることができる。) 今後のバージョンの POSIX.1 では、どちらの動作の実装も認められるように規定が変更される。 ファイルツリーを辿らないコマンド 二つ目の領域は、 ファイルツリーを辿らないコマンドの、 コマンドライン引き数のファイル名とし てシンボリックリンクが指定される場合である。 以下に述べる場合を除くと、 コマンドはコマンドライン引き数で指定された名前のシンボリックリ ンクを辿る。 例えば、 afile という名前のファイルを指しているシンボリックリンク slink が あったとすると、 コマンド cat slink は afile の内容を表示することになる。 大事な点として意識しておくべきなのは、 このルールが適用されるコマンドの中には、 オプション 次第ではファイルツリーを辿る場合があるコマンドもあるということである。 例えば、 コマンド chown file はこのルールに含まれるが、 コマンド chown -R file はツリーを辿る動作をするので あてはまらない (後者の場合は、3 つ目の領域に該当する)。 シンボリックリンクを辿るのではなく、 コマンドがシンボリックリンク自身に対して操作を行うこ とを明示的に指示したい場合、 例えば、 chown slink で slink がシンボリックリンクかどうかに 関わらず、 slink のファイル自身の所有権を変更したい場合は、 -h オプションを使用すべきであ る。 上記の例では、 chown root slink は slink が参照するファイルの所有権を変更するが、 chown -h root slink は slink 自身の所有権を変更する。 このルールにはいくつかの例外がある。 * コマンド mv(1) と rm(1) は引き数で指定された名前のシンボリックリンクを辿らないが、 それ ぞれシンボリックリンク自身の名前変更と削除を行おうとする。 (シンボリックリンクが相対パス でファイルを参照している場合、 そのシンボリックリンクを別のディレクトリに移動すると、動 かなくなることが非常によくある。 移動の結果、 パスが正しくないものになってしまうからであ る。) * ls(1) コマンドもこのルールの例外である。 昔からあるシステムとの互換性のため (ls(1) がツ リーを辿らない場合、つまり -R オプションが指定されなかった場合)、 ls(1) コマンドはオプ ション -H か -L が指定された場合、もしくはオプション -F, -d, -l が指定されなかった場合、 引き数として指定されたシンボリックリンクを辿る。 (ls(1) コマンドは、 ファイルツリーを辿 らない場合であっても、 オプション -H と -L がその動作に影響を与える唯一のコマンドであ る。) * file(1) コマンドもこのルールの例外である。 file(1) コマンドは、 デフォルトでは引き数で指 定されたシンボリックリンクを辿らない。 file(1) コマンドは、 -L オプションが指定された場 合、 引き数で指定されたシンボリックリンクを辿る。 ファイルツリーを辿るコマンド 次のコマンドは指定された場合もしくは常にファイルツリーを辿る: chgrp(1), chmod(1), chown(1), cp(1), du(1), find(1), ls(1), pax(1), rm(1), tar(1)。 重要なのは、 ファイルツリーを辿っている際に見つかったシンボリックリンクにも、 コマンドライ ン引き数として渡されたシンボリックリンクにも、 以下のルールが等しく適用される点である。 「1 つ目のルール」は、 ディレクトリ以外のファイルを参照するシンボリックリンクに適用され る。 シンボリックリンクに適用される操作はシンボリックリンク自身に行われるが、 そうでない場 合はリンクは無視される。 コマンド rm -r slink directory は slink を削除するとともに、 ファイルツリーを辿る途中で見 つけたシンボリックリンクも削除する。 シンボリックリンクは削除できるからである。 rm(1) が slink が参照するファイルに影響をおよぼすことはない。 「2 つ目のルール」は、 ディレクトリを参照するシンボリックリンクに適用される。 デフォルトで は、 ディレクトリを参照するシンボリックリンクを辿らない。 この動作はしばしば「物理的な」ツ リー探索 ("physical" walk) と呼ばれる。 これに対して (ディレクトリを参照するシンボリックリ ンクを辿る場合は) 「論理的な」ツリー探索 ("logical" walk) と呼ばれる。 一貫性を持たせるため、ファイルツリーを辿るコマンドが可能な限り従っている慣習がいくつかあ る。 * -H ("half-logical") フラグを指定すると、 参照先のファイル種別に関わらず、 コマンドにコマ ンドラインで指定されたシンボリックリンクを辿らせることができる。 このフラグは、 コマンド ラインの名前空間を論理的な名前空間のように見せるためのものである。 (常にファイルツリーを 辿るわけではないコマンドでは、 -R フラグを一緒に指定しない限り、 -H フラグは無視される点 に注意。) 例えば、 コマンド chown -HR user slink は slink が指すファイルを頂点とするファイル階層を 辿る。 -H は上記で説明した -h フラグとは同じではないことに注意。 -H フラグを指定すると、 アクションを実行する場合でも、 ツリーを辿る場合でも、 コマンドラインで指定されたシンボ リックリンクの解決 (dereference) を行う。 ユーザーがシンボリックリンクが指すファイル名を 指定したのと同じように見える。 * -L ("logical") フラグを指定すると、 参照先のファイル種別に関わらず、 コマンドが、 コマン ドラインで指定された名前のシンボリックリンクも、 ファイルツリーを辿る際に見つけたシンボ リックリンクも辿るようになる。 このフラグは、 名前空間全体を論理的な名前空間のように見せ るためのものである。 (常にファイルツリーを辿るわけではないコマンドでは、 -R フラグを一緒 に指定しない限り、 -L フラグは無視される点に注意。) 例えば、 コマンド chown -LR user slink は slink が参照するファイルの所有者を変更する。 slink がディレクトリを参照する場合、 chown はそのシンボリックリンクが参照するディレクト リを頂点とするファイル階層を辿る。 また、 chown が辿るファイルツリー内でシンボリックリン クが見つかった場合、 slink と同じように処理される。 * -P ("physical") フラグを指定すると、 コマンドはデフォルトの動作をするようになる。 このフ ラグは名前空間全体を物理的な名前空間のように見せるためのものである。 デフォルトでファイルツリーを辿らないコマンドでは、 -R フラグが同時に指定されなかった場合、 フラグ -H, -L, -P は無視される。 また、 -H, -L, -P は複数回同時に指定できるが、 最後に指定 されたオプションでコマンドの動作が決定される。 この動作は、 コマンドのエイリアスにある動作 を指定しておいて、 コマンドラインでその動作を上書きできるようにするためである。 コマンド ls(1) と rm(1) には、 これらのルールに対する例外がある。 * rm(1) コマンドは、 参照先のファイルではなく、シンボリックリンクに対して操作を行う。 した がって、 シンボリックリンクを辿ることはない。 rm(1) コマンドはオプション -H, -L, -P をサ ポートしていない。 * 古いシステムとの互換性を持たせるため、 ls(1) コマンドは少し違った動作をする。 オプション -F, -d, -l を指定した場合、 ls(1) はコマンドラインで指定されたシンボリックリンクを辿る。 -L フラグが指定された場合、 コマンドラインで指定された場合でも、 ファイルツリーを辿る際 に見つかった場合でも、 ファイル種別に関わらず、 ls(1) はすべてのシンボリックリンクを辿 る。
関連項目
chgrp(1), chmod(1), find(1), ln(1), ls(1), mv(1), rm(1), lchown(2), link(2), lstat(2), readlink(2), rename(2), symlink(2), unlink(2), utimensat(2), lutimes(3), path_resolution(7)
この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部 である。プロジェクト の説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。