◆ Windows のリンク機能
◆ ハードリンクとシンボリックリンクの中間みたいな機能 

Windows には 「ショートカット」「シンボリックリンク」「ジャンクション」「ハードリンク」と4つもリンク機能があります

Windows のリンク

ですが普通に Windows だけで使ってると「ショートカット」と「シンボリックリンク」だけで十分です
この2つの違いは主にユーザが使うかコンピュータが使うかです

ショートカットは エクスプローラなどの対応ソフトでショートカットのlnkファイルを開くと lnkファイルが指定するフォルダやファイルを開いたことにするもの
何を開くかの指定はコマンドラインで実行する文字列を書くので プログラムをオプションや入力ファイルなどの引数や作業用フォルダを設定して実行することができます

名前の通りショートカットらしい動きをします
ついでに ショートカットキーの設定までできたりします
また リンク先を移動させたりしても 多くの場合リンク先を追従してくれます
右クリックから作れて PC不慣れな人でも困らない作りです

欠点はプログラム上からパスとして lnkファイルを含むように指定しても lnkファイルはただのバイナリファイルということでフォルダ扱いされません


シンボリックリンクは Linux のとほぼ一緒です
コマンドからしか作れなくて リンク先を動かすと使えなくなる上級者向けです
エクスプローラなどでイジってる分にはショートカットと変わりませんが プログラム上でパスに含めることができます
相対パスでの指定も可能です


先にハードリンクも説明しておくと これも Linux のと同じで リンクが特定のファイル自体を指差すんじゃなくて 対象となるファイルがあるHDDの場所を指差すようなものです
リンクが作られるとどちらも 直接同じデータを見に行きます
対象となるファイルを通してHDDのデータへアクセスするわけじゃないので リンクを作った時の元ファイルを削除しても動作します

ハードリンクのイメージ
target.txt src.txt
↓ ↓
[00101100101010011101] HDDデータ

ハードリンク以外のイメージ
target.txt ← src.txt

[001010100101010111101] HDDデータ


では待ちに待った ジャンクションです……が どう便利だったかの説明は後のほうで書きます

ジャンクションの立ち位置は ハードリンクとシンボリックリンクの間です
元々 Windows ではジャンクションとハードリンクとショートカットの3つでシンボリックリンクができたのは最近のことです
そういうこともあって フォルダ配置の互換性を維持するためのリンクはジャンクションで実装されています
コマンドプロンプトで見ればわかりますが XP の頃にあった Document and …… や Application Data や All Users といったフォルダはジャンクションで存在します
なくしてしまうと 昔のソフトがXPとしてユーザフォルダへアクセスするときにエラーになってしまうのでXPのパスでもちゃんとアクセスできるようにされています

また 管理者権限なしで作成できるのも特徴です
Windows 7 までは管理者権限コマンドプロンプトを出すのはちょっとめんどうなのでどっちでもよければジャンクションでもいいと思います


ところで シンボリックリンクとショートカットはフォルダでもファイルでも使えますが ハードリンクはファイルのみ ジャンクションは フォルダのみとなっています

ハードリンクがファイルのみなのは Linux でも一緒です

ジャンクションが便利

さて 本題のジャンクションが便利なときのお話です

Windows のフォルダを Linux でマウントします
cifs マウントです

このときに共有する Windows のフォルダ内にWindowsで作ったシンボリックリンクがあっても Linux では正しく開けず使えません
逆に Linux でシンボリックリンクを作ろうとしてもエラーで作ることができません

ですが Windows でシンボリックリンクではなく ジャンクションを作ると Linux からでもそのリンクが使えます

役に立つのはこんなとき

パスを短くするためにCドライブ直下にしますが C:\share フォルダを共有しているとします
そのときに C:\data\sample フォルダも Linux から使いたくなりました
C:\data\sample というパスも別の用途で使っているので移動してしまうわけにはいかないです
C:\share\sample --> C:\data\sample とシンボリックリンクしても上で書いたように Linux 側でそれを解決できません

移動して逆に C:\data\sample --> C:\share\sample にシンボリックリンクというので解決できはするのですがなんか気持ちよくないです

そんなときに ジャンクションで C:\share\sample --> C:\data\sample をリンクすれば Linux からも見ることができます

すごく便利!!

jnc01

Windows ではリンクを作るときは mklink コマンド
/J でジャンクション
/H でハードリンク
未指定はシンボリックリンクです

フォルダへのリンクの場合は /D が必要です
といっても ハードリンクではフォルダへのリンク作れなくて ジャンクションはフォルダのみなので シンボリックリンクつくるときのみ使うオプションです

Linux と違って リンク名  リンク先 の順番でパスを書きます
逆なので注意です

jnc02


ハードリンクにしようとしたら フォルダなのでできなくてなんか方法ないか調べてると ジャンクションはシンボリックリンクと同じようなものでハードリンクっぽいことができるとか聞いてやってみたらできた という発見です

追記: シンボリックリンクでも使える場合

Windows で作ったシンボリックリンクは Linux でマウントしたら使えないと書きましたが 使える場合もあります

Windows で作ったシンボリックリンクは Linux 上でも シンボリックリンク として扱われます
なので 絶対パスで指定しても ルートやパスが Windows と Linux では違うので使えません
相対パス指定なら Linux でマウントしているディレクトリ以下なら問題なく使えます
マウントしているディレクトリより上の階層にリンクしても存在するディレクトリが違うので使えません

図にしてみると
C:\data\
sample\
share\ (← 共有フォルダのルート)
image\
dir\
sample1 --> C:\data\sample ×
sample2 --> ..\image ○
sample3 --> ..\..\data ×
#sudo mount -t vboxsf share /mnt/windows

/mnt/
windows/
image/
dir/
sample1/ --> C:\data\sample ???
sample2/ --> ../image ○
sample3/ --> ../../data /mnt/data なんてない
という感じです


ジャンクションを使うと Linux 上ではシンボリックリンクではなくそこにディレクトリがあるように扱われます
ls -l で見ても 「-> ../」 みたいのがありません

なので シンボリックリンクだとダメでジャンクションを使えば大丈夫というわけです