Cygwinでシンボリックリンクをln -sコマンドで作るとExplorerから中身を見れないし、
Windowsでショートカットを作るとCygwinの中からは中身を正しく見ることができません。
CygwinをCygwin内だけで閉じてる場合は良いのですが、 Cygwin側からLinuxコマンドでWindows内のファイルを整理したり編集したいと思う場合これはとても不便です。
ということで今回はWindowsのシンボリック機能を使って両方で使えるリンクを作る方法についてです。
Windowsのシンボリックリンク
Windowsのショートカットはリンク先のパスが書かれたファイルで、
Linuxにおけるシンボリックリンクなどとは別物です。
従ってCygwinから見るとディレクトリもただの.lnkファイルで
中を無理やり見るとパスっぽいものが含まれた文字列が見れるだけです。
一方、LinuxのシンボリックリンクはWindowsはサポートしてないので、
Cygwinで作られたシンボリックリンクはExplorerなどでは通常ファイルに見え、
無理やりメモ帳などで開いてみると<symlink>を含むこちらもパスの情報の文字列が表示されます。
これではちょっと面倒なんですが、実はWindowsにもシンボリック機能があり、 Windows Vistaから使える様になってます 1 2。
この機能はLinuxのそのものと近い機能になっているらしくCygwinからでもシンボリックリンクに見えます。
ですので両方でシンボリックリンクを使えば良いのですが、 通常はDOSプロンプト等からしか作れません。 いちいちOSプロンプトから作るのではやってられないので、 シンボリックリンクを簡単に作る方法を紹介します。
Explorer等からシンボリックリンクを作る
シンボリックを作る機能があるのにあまり知られてないのは、 右クリック等から作れるのはショートカットだけだからだと思います 3。
そこで、 Link Shell Extension というソフトをインストールします。
このソフトをインストールすると、右クリックメニューにリンク元として作成と言う項目が出来、
あるファイルやフォルダでこの項目を選択肢、
他のフォルダで右クリックするとリンクを作成という項目が
選べる様になっているのでこれを選択するとシンボリックリンクが作成されます。
ショートカットと同じアイコンになります。
右クリックからプロパティをみてみると、リンクという項目があり、
シンボリックリンクであることが確認できます。
(下の絵はVista)

このファイルはCygwin側からはln -sで作ったものと全く同じに見えます。
CygwinでWindowsのシンボリックリンクを作る
まず、Cygwinでのコマンドの前に、DOSプロンプトでのシンボリックリンクの作り方について。
Windowsのシンボリックリンクはmklinkと言うコマンドで作れます。
DOSプロンプトでmklinkとしてみると
C:\>mklink
シンボリック リンクを作成します。
MKLINK [[/D] | [/H] | [/J]] リンク ターゲット
/D ディレクトリのシンボリック リンクを作成します。既定では、
ファイルのシンボリック リンクが作成されます。
/H シンボリック リンクではなく、ハード リンクを作成します。
/J ディレクトリ ジャンクションを作成します。
リンク 新しいシンボリック リンク名を指定します。
ターゲット 新しいリンクが参照するパス (相対または絶対)
を指定します。
となり、オプション無しならシンボリックリンク、さらにハードリンクや ジャンクション(Windowsの古いシンボリックリンク的な物)も 作れることが分かります。
lnコマンドと違い、フォルダ(ディレクトリ)指定の場合は/Dが必要です。
このコマンドをCygwinから呼ぶには
$ cmd /c mklink target.txt original.txt
の様にcmdコマンドを使ってmklinkを呼び出します。
注意しなくてはいけないのは、リンク元とリンク先の順番がlnの場合と逆だ、ということです。
lnの場合は
$ ln -s original.txt target.txt
の様な形なので。
これを毎回打つのは大変だし、lnを使ったスクリプトも使い回しをしたいので、
次の様なWraper関数を作りました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | |
適当に.bashrc等に加えてください。
Cygwinであるかどうかのチェックも入れたので、
MacやLinuxと共通の.bashrcに入れてもOKです。
これで普通にln -s original.txt target.txtとすればtarget.txt
というシンボリックリンクが出来ます。
Windows側から見るパスとCygwin内でのパスは違うので、 Windowsでのフルパスを取ってきて、それに対するシンボリックリンクを作っています 4 。
例えばC:\cygwin\home\user\a.txt
というファイルに対してC:\cygwin\home\user\b.txtというリンクを作るとする
(ついでにオリジナルのlnも作ってみる)と、
$ echo aaa > a.txt
$ ln -s a.txt b.txt # using mklink
$ /usr/bin/ln -s a.txt c.txt # using original ln
とする、Cygwinで見ると
$ ls -l
-rw-r--r-- 1 user None 4 Jun 25 23:00 a.txt
lrwxrwxrwx 1 user None 23 Jun 25 23:01 b.txt -> /home/user/tmp/a.txt
lrwxrwxrwx 1 user None 5 Jun 25 23:01 c.txt -> a.txt
となります。 どうやらWindowsのシンボリックリンクの方が色々20bytesほど情報が大きい様です。
さらに同じディレクトリにExplorerからショートカットを作ってみると
$ ls -l
-rw-r--r-- 1 user None 4 Jun 25 23:00 a.txt
-rwxr-xr-x 1 Administrators None 736 Jun 25 22:12 a.txt.lnk
lrwxrwxrwx 1 user None 23 Jun 25 23:01 b.txt -> /home/user/tmp/a.txt
lrwxrwxrwx 1 user None 5 Jun 25 23:01 c.txt -> a.txt
と言った感じに、ショートカットが桁違いに大きいサイズです。 それでも1KB以下なのでよっぽどのことが無い限り問題ないわけですが、 さすがに10分の1以下で済むのであればシンボリックリンクを使いたいところです。 (互換性以外に何か問題はあるんでしょうか…?)
追記: 2015/01/25
コメントで教えてもらいましたが、
上の様にわざざlnをmklinkにラッパーをかけなくても、
環境変数CYGWINにwinsymlinksを設定することで
Cygwinのln -sコマンドをWindowsのシンボリックリンク作成コマンドへ変更することができます。
設定はWindowsの環境変数の方でするか、.bashrc等で、
1 2 3 | |
とでもしておけばOK。CYGWINへはオプションを空白区切りで入れてく様なので
デフォルトの値を残すように上の様に追加する形で設定。
これで通常のlnコマンドを使ってWindowsのシンボリックリンクが作れる様になります。
追記ここまで
追記: 2015/01/25
winsymlinksをちょっと勘違いしてましたが、上のリンク先ページをよく読めば分かるように、
winsymlinksだけを設定するとWindows側からはショートカットに見え、
Cygwinからはシンボリックリンクに見えるリンクができます。
(winsymlinks:lnkとしても同じ。)
winsymlinks:nativestrictとすると
Windows側でもシンボリックリンクな機能のリンクができます。
ただし、この場合シンボリックリンクが作成できないような環境ではエラーが出ます。 (NTFSでしかサポートされないのでディスクがFATだったり、 またはWindows 10などでシンボリックリンクを禁止している場合や 管理者しか作成できない場合に通常ユーザーだった利するとき。)
winsymlinks:nativeとすると
Windowsのシンボリックリンクを作れない場合には
Cygwinの通常のシンボリックリンクを作ります。
つまり、Windowsのシンボリックリンクを扱えない時は
Windows側からは使えないリンクになります。
winsymlinksまたはwinsymlinks:lnk: Windows側からショートカットに見えるリンクを作成。winsymlinks:native: Windows側からシンボリックリンクに見えるリンクを作成。もしシンボリックリンク作成に失敗した場合、Cygwinの通常のシンボリックリンクを作る。(Windows側からは使えないリンクになる。)winsymlinks:nativestrict: Windows側からシンボリックリンクに見えるリンクを作成。もしシンボリックリンク作成に失敗した場合はエラーを返す。
winsymlinks:lnkだと、通常の作業ではCygwinではシンボリックリンクだし
Windowsではショートカットとして使えるのでほとんど問題はないのですが、
VimperatorやAutoHotKeyで
メインファイルからさらに他のファイルを読み込んだりするとき、
きちんと見えなくてうまく動かない場合があります。
なのでできればすべてWindows側もシンボリックリンクにしておくと 一番問題なく使えるはずです。
追記ここまで