カルボナーラ街道

計測と観察

dotfiles盆栽記5: treeのオプション指定をデフォルトで実行するようにした

盆栽日和。

github.com

モチベーション

treeでドットから始まるディレクトリを表示する時はaオプションを付与するが、Git管理下のディレクトリの場合はオプションで .git を除外しないと .git 配下もtreeで表示されてしまう。行数が多くなり大変見づらい。

> tree -a | wc -l    
      71

> tree -a -I ".git" | wc -l
      10

こうした

alias tree='cmd="command tree -a -I .git"; echo $cmd; eval ${cmd}'

アプローチ

あまりコマンド周りの脳内インデックスを増やしたくないので通常のtreeの呼び出しを変更したい。お行儀は悪いが。

alias tree='tree -a -I .git'

これで良いのでは?と思って試したらエイリアスの方が優先された。これで良さそうだが、通常のtreeとは異なることを実行時に知りたい。

alias tree='cmd="tree -a -I .git"; echo $cmd; eval $cmd'

コマンドを標準出力してみた。これでいける!と思ったら以下の表示になった。

> tree
tree -a -I .git
tree -a -I .git
tree -a -I .git
tree -a -I .git
tree -a -I .git
....

どういうことだ。おそらく以下の感じで実行されるっぽい。

  1. cmd="tree -a -I .git: 文字列を変数格納
  2. echo $cmd: 文字列を標準出力
  3. eval $cmd: tree -a -I .git が実行されるが、このtreeがエイリアスのtreeを呼んで1に戻り、無限に呼ばれる

3ではエイリアスではなくオリジナルのtreeを実行させたい。こういうときに command が有用みたい。

alias tree='cmd="command tree -a -I .git"; echo $cmd; eval ${cmd}'
> tree | head -n 6
command tree -a -I .git
.
├── .git-hooks
│   └── commit-msg
├── .vscode
│   ├── keybindings.json
│   └── settings.json

めでたし。

参考