シンボリックリンク先を実体のパスで開く

※ 後日、もっと楽な手順あったことに気づいたので、以下の記事の方をおすすめします。

https://yuuchika.com/linux-symboliclink-realpath-cd/

今回はLinuxのコマンド操作を少し快適にする方法を紹介します。 この記事を書くための動作確認に使用した環境は以下になります。

シンボリックリンクで少し快適に

ソフト開発のプロジェクトなどで、ディレクトリ移動の手間を少し削減するためにシンボリックリンクを使用することはありませんか? 私はあります。

例えば、下の図のようなディレクトリ構造だった場合。

user1のホームディレクトリは /home/user1 ProjectAの共通ヘッダファイルの置き場が /projects/projectA/header ProjectAのuser1が担当するモジュールmoduleXのソースファイルの置き場が /projects/projectA/source/moduleX とした場合、

user1は、最も頻繁にアクセスするディレクトリが /projects/projectA/source/moduleX になります。 そんなとき、毎回 moduleX ディレクトリまでのフルパスを入力して移動するのが面倒くさいので、シンボリックリンクを作ります。

[user1@server ~]$ ln -s /projects/projectA/source/moduleX prjAmodX

すると、下の図のようになります。

これで、user1はログインしたあと、

[user1@server ~]$ cd prjAmodX

とコマンドを叩くだけで、ソース編集したいディレクトリに移動することが出来ます。

それでも少し不便

moduleXの担当者なので、moduleXディレクトリに気軽に移動できるようになったuser1ですが、関連する別モジュールであるmoduleYのソースを少し見たくなりました。

moduleYのディレクトリに移動するために一旦、一つ上のディレクトリに移動します。

[user1@server prjAmodX]$ cd ..

そして、いろんなモジュールのディレクトリが並ぶのを想定して、ファイルリストを表示します。

[user1@server ~]$ ls
prjAmodX

あれ?

シンボリックリンク先に移動した場合、パスは実体のものではなくシンボリックリンクのものに置き換えられてしまっているのです。 なので、"cd .." を実行した時点では、 /projects/projectA/source/moduleX ではなく、/home/user1/prjAmodX というパスがカレントディレクトリになっていました。 そのため、 "cd .." で、/home/user1 に移動した、ということになります。

ではどうすればいいの?

moduleYのディレクトリ名を正確に覚えている場合は、

[user1@server prjAmodX]$ cd ../moduleY

でmoduleYのディレクトリに移動できます。

この場合、

[user1@server moduleY]$ pwd
/projects/projectA/source/moduleY

と、シンボリックリンクではなく実体のパスとしてカレントディレクトリが切り替わります。

しかしこのやり方の場合、Tab補完が利かないため、本当に正確にディレクトリ名を覚えている必要があります。 そこで使用するのが、readlinkコマンドです。

readlinkコマンドは、シンボリックリンクの実体パスを表示するコマンドですが、 -f オプションを付与することで、ファイルやディレクトリ(シンボリックリンクに限らず)のフルパスを表示してくれます。

これを活用すると、以下のようにシンボリックリンク先に移動したあとで実体パスにカレントディレクトリを切り替えることが可能です。

[user1@server ~]$ cd prjAmodX
[user1@server prjAmodX]$ cd `readlink -f .`
[user1@server moduleX]$ pwd
/projects/projectA/source/moduleX

こうすることで、元々参照したかったモジュールディレクトリ一覧が確認できます。

[user1@server moduleX]$ cd ..
[user1@server source]$ ls
moduleX  moduleY

毎回このコマンドを打つのが面倒くさい

やりたいことをやる方法はわかりました。 でも、毎回 cd `readlink -f .` だなんて打つのは面倒くさいですよね。

なので、シェルスクリプトエイリアスを使用して、もう1段階手軽にしましょう。

まず、~/bin/ などパスを通したスクリプト置き場のディレクトリに以下のようなスクリプトファイルを作ります。

cdl.sh

#!/bin/sh

cd $@
cd `readlink -f .`

続いて、 .bashrc に以下の1行を追記します。

alias cdl="source cdl.sh"

あとは、source .bashrc などで.bashrcをロードしてやると準備は完了です。 cd コマンドの感覚で cdl としてやるだけで、シンボリックリンク先に移動する際に一発で実体ディレクトリに移動できるようになります。

[user1@server ~]$ cdl prjAmodX
[user1@server moduleX]$ pwd
/projects/projectA/source/moduleX