(Bash)CDPATH スマートにcdを使う

1-3.コマンドライン操作

CDPATHにパスを登録することで、cdで楽ができることは分かりましたが、新たに遭遇したディレクトリ構造において、どのディレクトリをCDPATHに登録すれば効率的かわかりません。

そのような場合は、すべてのディレクトリを対象にCDPATHへ登録してしまえば良いです。

linuxのカーネルソースを例に確認してみましょう。

まずはカーネルソースの取得です。ダウンロードするためにwgetもインストールしておきます。また、tar.xz圧縮ファイルは、tarコマンドで解凍(伸長)できます。

~# apt install wget
~# cd /usr/src
/usr/src# wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.7.9.tar.xz
/usr/src# tar xJf linux-5.7.9.tar.xz
/usr/src# ln -s linux-5.7.9 /usr/src/linux
/usr/src# cd linux
/usr/src/linux#

カーネルのディレクトリ構造において、一番長いディレクトリ名の長さはいかほどでしょうか。wcで確認してみます。

/usr/src/linux# find -type d | wc -L
83
/usr/src/linux# 

83文字が最長のようです。近い長さのディレクトリを探してみます。sedを使います。

/usr/src/linux# find -type d | sed -ne '/^.\{77,83\}$/p'
./tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/uapi/linux
./drivers/staging/media/phy-rockchip-dphy-rx0/Documentation/devicetree/bindings
./drivers/staging/media/phy-rockchip-dphy-rx0/Documentation/devicetree/bindings/phy
/usr/src/linux# 

さて、この長いパスをいちいち手で入力していては骨が折れるというか、本当に折れるかもしれません。CDPATHへ登録してみましょう。
やはり、findを使います。CDPATHは:(コロン)で区切って登録すれば良いので、findの結果を:(コロン)で区切ってやればよいです。

/usr/src/linux$ CDPATH=`find -type d | tr \\\n :`
/usr/src/linux$ 

これでCDPATHへの登録が完了しました。
試しに、最長のディレクトリ〜bindings/phyにディレクトリ切り替えしてみましょう。

/usr/src/linux# cd bindings/phy
/usr/src/linux/drivers/staging/media/phy-rockchip-dphy-rx0/Documentation/devicetree/bindings/phy
/usr/src/linux/drivers/staging/media/phy-rockchip-dphy-rx0/Documentation/devicetree/bindings/phy# 

うまく行きました。
他のディレクトリにも切り替えてみます。

/usr/src/linux# cd linux
/usr/src/linux/include/linux
/usr/src/linux/include/linux# 

あれ、どうしたことでしょう。パスが期待していたものと異なります。なぜでしょうか。
実はlinuxというディレクトリは、複数存在しています。
findすると、以下のように6つ確認できました。

/usr/src/linux# find -type d -name linux
./include/linux
./include/uapi/linux
./tools/include/linux
./tools/include/uapi/linux
./tools/testing/scatterlist/linux
./tools/testing/selftests/rcutorture/formal/srcu-cbmc/include/linux
./tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux
./tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/uapi/linux
./tools/testing/selftests/powerpc/primitives/linux
./tools/testing/radix-tree/linux
./tools/perf/include/bpf/linux
./tools/perf/util/include/linux
./tools/bootconfig/include/linux
./tools/virtio/linux
./tools/virtio/uapi/linux
./arch/um/include/linux
./scripts/gdb/linux
/usr/src/linux# 

linuxというデイレクトリについて、CDPATHの方がどのように登録されているか確認してみます。

/usr/src/linux# echo $CDPATH | tr : \\n | grep linux$
./include/linux
./include/uapi/linux
./tools/include/linux
./tools/include/uapi/linux
./tools/testing/scatterlist/linux
./tools/testing/selftests/rcutorture/formal/srcu-cbmc/include/linux
./tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/linux
./tools/testing/selftests/rcutorture/formal/srcu-cbmc/empty_includes/uapi/linux
./tools/testing/selftests/powerpc/primitives/linux
./tools/testing/radix-tree/linux
./tools/perf/include/bpf/linux
./tools/perf/util/include/linux
./tools/bootconfig/include/linux
./tools/virtio/linux
./tools/virtio/uapi/linux
./security/selinux
./Documentation/translations/zh_CN/video4linux
./arch/um/include/linux
./scripts/selinux
./scripts/gdb/linux
/usr/src/linux# 

当然ですが、findの結果と同じになります。
つまり、重複しているディレクトリの場合は、CDPATHの最初に登録したパスが適用されるわけです。

ではカーネルソースにおいて、ディレクトリ名の重複はどのぐらいあるのでしょうか。

/usr/src/linux$ tree -id | sort | uniq -d | wc -l
475
/usr/src/linux$ 

475件ありました。
どのようなディレクトリが重複しているのでしょうか重複の多い10件をあげてみました。

/usr/src/linux# tree -id | sort | uniq -cd | sort | tail
     20 common
     21 boot
     27 mm
     28 configs
     28 kernel
     28 mach
     40 lib
     50 uapi
     88 asm
    113 include
/usr/src/linux# 

includeは、113件もディレクトリ名として使われています。
このような重複件数の多いディレクトリ構成で、果たしてCDPATHは役に立つのでしょうか。

重複していないディレクトリ名も確認してみましょう。

/usr/src/linux$ tree -id | sort | uniq -u | wc -l
1782
/usr/src/linux$ 

1782件も見つかりました。
重複しているディレクトリよりも多いので、CDPATHが有効に使えるのではないでしょうか。

コメント

タイトルとURLをコピーしました