cdで無限の可能性を
集え!OITer!!! OIT Advent Calender 2016!!!!
この記事は、 OIT Advent Calendar 2016の5日目の記事です。
5日目の今日も隊長がお送りします。
皆さんcd
コマンド使ってますか。
cmdにもシェルにもふつーにありますよね。
ls
とかとならんでめちゃ使うコマンドの一つだと思います。
よく使うのでcd
は快適であってほしいです。
ls
コマンドはオプションが沢山あり、よく使うls -a
とかls -l
なんかはエイリアス登録して使ってる人も多いんじゃないですか?
しかしcd
のman
を見ると・・・
http://ss64.com/bash/cd.htmlss64.com
オプションが二つしかありません。(そのうち一つはデフォルトでON)
これってこれ以上快適にできないってことじゃん!!!!
そうです。
ぼくのかんがえたさいきょうのcd
こまんど その名は cdx
_人人人人人人人人人人人人_
> そんなんありません! <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄
(たぶん)
なら自分でつくろうか
cd
コマンドだけでも全く問題はないんですが
僕みたいに車輪の再発明をした後、その車輪にスパイクとか発光するやつとかをつけちゃうような奴はこういうことが大好きです。
まぁcdx
みたいなのはないと思うので車輪の再発明にあたるかは微妙ですが・・・
(2016/12/05 13:55 追記)cdxみたいなのありました・・・!こっちのがすごそうです! qiita.com (追記終わり)
車輪の再発明(しゃりんのさいはつめい、英: reinventing the wheel)は、車輪を題材にした慣用句であり、世界中で使われている。「広く受け入れられ確立されている技術や解決法を知らずに(または意図的に無視して)、同様のものを再び一から作ること」を意味する。 -車輪の再発明 Wikipedia
使う言語はbash
です。
履歴機能
まずは
cdx
に履歴を付けます。
履歴はいつでも参照できて、番号指定でそこへ移動できるようにします。
パスをどこかファイルへecho
しておいてそれを読み出すようにします。
if [ $cdx_option == "-h" ]; then line=$2 if [ "$line" == "" ]; then line=`cat ~/.cdx_history|wc -l` lineStart=`echo $line - 10|bc` if [ $lineStart -lt 1 ]; then lineStart=1 fi cat -n ~/.cdx_history|sed -n "$lineStart,${line}p" cd_flag=0 elif [ $line == "clear" ]; then echo "" > ~/.cdx_history else change_to=`cat ~/.cdx_history | sed -n "$line,${line}p"` fi fi ###中略### #cdするまえに echo `pwd` >> ~/.cdx_history
実はC#でJsonを使って書いたんですけど思いのほか長くなってしまった・・・のでやめました・・・。
これで~/.cdx_history
にどんどん履歴がたまっていきます。
cdx.sh -h 1
とすると履歴ファイルの1行目へ移動します。
cdx.sh -h
とだけ打ち込むと最新の履歴10件を表示して終了します。
無限に履歴をため込むのでときどきcdx -h clear
としてやるといいですね。
(エンコードの調子が悪い)
表示をかっこよくする
ぼくはまだ中二病を卒業できてないところがあるので表示がカッコいいとテンションが上がります。
なのでcd
した後に単に移動先のディレクトリをpwd
するだけじゃなくて色々表示しちゃいます。
if [ $cd_flag = 1 ]; then bef_dir=`pwd` cd $change_to > /dev/null if [ $? = 1 ]; then echo -e -n "${change_to}\nが見つかりませんでした。\n作ろうか?(y/n):" read ans if [ $ans == 'y' ]; then mkdir $change_to cd $change_to > /dev/null fi else echo -e " ${clr_Black}--> ${clr_main}cdx ${clr_Black}: ${clr_green}$bef_dir${clr_Black} ->>>${clr_green} `pwd`${clr_reset} " fi fi
さっきの部分のelse
側はcd
に成功した場合に通りますのでそこでカッコイイ表示を出してやります。
これがカッコよく感じるかは個人差があるのであれですが・・・
ブックマーク機能
次はブックマークを作ります。
いつもアクセスするディレクトリとかにはできるだけ短いキーストロークで移動したいもんです。
たとえば
cdx 0 #ブックマークの0番目に移動
とこんな具合に
まずブックマークは ~/.bashrc
に記述するようにします。
こんな感じで
#~/.bashrc #cdx bookmark export cdx_bookmark=("ブックマーク0" "ブックマーク1")
環境変数cdx_bookmark
を作成してそこにブックマークしておきたいディレクトリを記述します。
次にcdx.sh
にこれを読み出してインデックス通りに移動するように追記します。
#!/bin/bash ## cdx is hyper cd command ##color setting clr_error="\e[1;31m" clr_main="\e[1;35m" cdx_bm_arg=$1 cd_flag=1 change_to=$HOME if expr "$cdx_bm_arg" : "[0-9]+" > /dev/null ; then if [ $cdx_bm_arg -ge ${#cdx_bookmark[@]} ] || [ $cdx_bm_arg -lt 0 ]; then echo -e "${clr_error}[ブックマークの範囲外です]" cd_flag=0 fi #読み出し change_to=${cdx_bookmark[$cdx_bm_arg]} else #引数のところへcd change_to=$cdx_bm_arg fi if [ $cd_flag = 1 ]; then cd $change_to > /dev/null fi
これで. ./cdx.sh 0
とかするとcdx_bookmark
の0番目を読み出してcd
できるようになります。
でもこれだけだとなんか寂しいのでもう少し拡張します。
#!/bin/bash #cdxの補完 _cdx_complete(){ case $2 in [0-9]* ) COMPREPLY=( `echo "${cdx_bookmark[$2]}"` ) ;; *) ;; esac } complete -d -F _cdx_complete cdx
これは
cdx
の補完を行う記述です。Tabキー押したら発動するあれです。
cdx 0
としたとき
0
の部分に実際のパスを展開してくれます。
こんな感じで
※書いただけでは使えません。
さらに 一時ブックマーク みたいなのも作りましょう。
$cdx_option=$1 if [ $cdx_option == "bm" ]; then export CDX_TMP_BM=`pwd` echo -e "${clr_green}Temporary BookMark${clr_Black} <-- ${clr_green}`pwd`" cd_flag=0 fi if [ $cdx_option == "b" ]; then change_to=$CDX_TMP_BM cd_flag=1 fi
こうすると「きょうの作業ディレクトリはね~ここなの!」とcdx bm
してやれば
どこかに移動しててもcdx b
ですぐに戻れます。
移動先のディレクトリが無かったら作るか訊く
これできたら結構うれしいですよね?
cd
コマンドが「そのようなファイルやディレクトリはありません(冷酷)」とか言ってくると
無いんじゃなくてつくるんだよ!って感じます。
それでは
if [ $cd_flag = 1 ]; then cd $change_to > /dev/null if [ $? = 1 ]; then echo -e -n "${change_to}\nが見つかりませんでした。\n作ろうか?(y/n):" read ans if [ $ans == 'y' ]; then mkdir $change_to cd $change_to > /dev/null fi fi fi
cdx.sh
の最後のif
文の中をこういう風に変えます。
読んだら分かりますがcd
に失敗したら訊いて作って移動します。great
ひとつ前にいたディレクトリにすぐもどれる
pushd
とpopd
というコマンドがあるのを知ってますか?
これpush
,pop
ってところから想像つくと思うんですけど、移動するときにスタックにパスを残しておけるんです。
なのでpopd
を使えば一瞬でひとつ前のディレクトリに移動できるわけです。
しかし
みなさんここでお手元のキーボードをご覧ください。
無い方のために画像用意しました。
試しにpopd
って打ち込んでみてください。
やりました?
結構キーストローク長くないですか??え?そうでもない?
ならpushd
はどうですか?
うん長いね?
それにディレクトリ変えたいだけなのにいくつもコマンドあるとか無くない?
なのでcdx
に含んでしまいましょう。
といってもさっきまでのスクリプト内のcd
をpushd
に変えて、popd
をcdx -p
という形で呼び出せるようにするだけです。
if [ $cdx_option == "-p" ]; then bef_dir=`pwd` popd if [ $? = 1 ]; then echo -e " ${clr_Black}--> ${clr_main}cdx ${clr_Black}: ${clr_green}$bef_dir${clr_Black} ->>>${clr_green} `pwd`${clr_reset} " fi cd_flag=0 fi
正直cdx -p
ってpopd
よりなげーじゃんって思ってますけどいいんです。
ひとつにまとまっている。これが重要です。
そしてこれpopd
ってコマンドラインから打ち込んでもちゃんとひとつ前のディレクトリに移動できます。(当然だけど)
探し物してるときに自動でlsしてくれる
皆さんLinux上で探し物するときcd
→ls
→cd
→ls
→cd
→ls
→・・・ってしません?。僕はします。
探し物をしているときっていうのはcd
→ls
というステップを踏みます。踏め!
なので何回目か以降はcdx
が自動的にls
してくれるようにします。
さて、探し物しているかどうかをcdx
は判断しないとダメなんですが・・・それには~/.bash_history
を使います。
history -a line=`cat ~/.bash_history|wc -l` lineStart=`echo $line - 6|bc` if [ $lineStart -lt 1 ]; then lineStart=1 fi if [ `cat ~/.bash_history|sed -n "$lineStart,${line}p"|grep "ls"|wc -l` -ge 2 ]; then echo -e "${clr_main}探し物ですか?${clr_reset}" ls -la fi
pushd
に成功した後のelse
にこれを突っ込みました。
まず、~/.bash_history
を更新します。その次に~/.bash_history
の下から6行を見てls
が2つ以上あればls -la
を実行します。
なんだかハイテクですよね。
(エンコードの調子わる)
作ったコマンドを使えるようにする
このままでは呼び出すときに
. [cdx.shまでのパス] [もろもろの引数]
としないと使えません。
cd
系のコマンドをスクリプト内で使ってもスクリプト内しかディレクトリが変わらないのでsource(略系は .)
コマンドで反映するようにします。
でもこれ 明らかに面倒
なので~/.bashrc
をごにゃごにゃします。
#~/.bashrc cdx() { . [cdx.shまでのパス] $@ } . [complete.shまでのパス]
関数として定義してやればいいのです。
さらにcomplete.sh
も同時にsource
してやれば補完ができるように!
うーんgreat
最後に
いかがでしたか?cdx
、魅力的なコマンドになったと思いませんか?
今回ぼくはcdx
をこの記事に合わせて作り直しました。(作り直す前のはここ)
結構気に入っててふつーに使ってます。みんなも使ってくれたらうれしいです。
一応オプションのこととかまとめておきます。
オプション | 引数 | 説明 |
---|---|---|
-p | なし | popdが呼ばれる |
-h | なし | 最新の移動履歴10件が表示される |
-h | 番号 | 番号の履歴へpushdする |
なし | なし | $HOMEへpushdする |
なし | パス | パスへpushdする |
b | なし | 一時ブックマークへ飛ぶ |
bm | なし | カレントディレクトリを一時ブックマークする |
なし | 番号 | ブックマークを読みだしてpushdする |
シェルスクリプトはかなり自由なのでホントいろいろできます。既存のコマンドもこうすればよりよくなります。
それに書き方も単純です。型がないですし楽です。Cが書けてggれる人なら簡単に書けますYO!
今回作ったcdx
コマンドはここにあります。ぷるりくもお待ちしてる。
github.com
適当にgit clone
したりzip
とかでもってきて↑のように~/.bashrc
をごにゃごにゃすれば使えるようになります。
それでは良いcdx
ライフを!