Bashのcdコマンドでお気に入りのパスに一発で移動する方法

2021/11/22

UNIX

t f B! P L

朝起きて仕事を始めるぞー!というとき、まずプロジェクトのフォルダへ移動する。

cd path-to-your-project

と打ち込むわけだが、バイト掛け持ちの私は常に複数のプロジェクトを抱えていることもあり、毎度毎度毎度違うパスを打ち込むのが本当にめんどくさい(bashの補完があるとはいえ)。

というわけで、cdでブックマーク的なことをできるようにします。
まぁ厳密には1発じゃなくて2発なんですけどね。
OSはUbuntuを想定。

コード

まずホームディレクトリに bashmark というディレクトリを作り、以下のシェルスクリプト bm.shfavorite.txt というお気に入りパスを書いたテキストファイルを置く。

function bashmark () {
	local array=("${HOME}")

	local lines=`cat ${HOME}/bashmark/favorite.txt`

	local line
	for line in $lines; do
	    # echo "$line"
	    array+=( "$line" )
	done

	local i
	for ((i=0; i < ${#array[@]}; i++)); do
	    echo "[$i] ${array[$i]}"
	done

	local j
	read j

	cd ${array[$j]}
}

bashmark

favorite.txtはプレーンテキストで、1行1パス形式で、ブックマークしたい絶対パスを記述する。

なお、bashのお気に入りパスでぐぐるとbashmarkというレポジトリが出てくる。
名前がカッコいい&わかりやすいため、名前だけ拝借しただけで何の関係もありません。
ディレクトリ名も適当に好きなものにしてもらってOKです。

実行方法

実行すると、favorite.txtに記述されたパスに連番がついて表示され、移動したいパスの番号をtypeすると、そのパスへcdしてくれるというのもの。

ところが、シェルスクリプトはサブシェルで実行されるので、そのまま実行してもcdできていない。

サブシェルが終了すると、呼び出しシェル側の環境には通常は副作用(定義した変数やcdなどの移動の結果)が残らない。
※もちろんファイルに書き込んだりした結果は残ります。

どうするかというと source コマンドで上記のスクリプトを実行する。これで副作用(cdの結果)が呼び出しシェルにも残る。

ただ、bashmarkを実行するための変数はいらなかったりするので、function内にローカル変数として定義しておくとよし。

最後にsourceコマンドの実行をbash_aliasに記載してめでたしめでたし。

alias cdb='source ~/bashmark/bm.sh'

その他ポイント

パスの配列に初期値としてHOMEのパスを入れているが、これは空配列だと要素の追加ができないというbashの謎仕様があるため。
なんでもいいからよく使うパスを1つ書いておくとよし。

お気に入りパス自体は、プロジェクト開始、終了で書き換えたい要望もあるため、favorite.txtはプレーンテキストにしてさくっと書き換えられるようにしている。

めっちゃ参考になったスレッド

https://stackoverflow.com/questions/255414/why-cant-i-change-directories-using-cd-in-a-script

QooQ