じゃあ、おうちで学べる

本能を呼び覚ますこのコードに、君は抗えるか

Fish Shell の abbr で使う。キミが好きだよ、エイリアス

はじめに

ターミナルで作業をしていると、同じコマンドを何度も入力することがありますよね。git checkout -b feature/new-branch や kubectl get pods --all-namespaces のような長いコマンドを毎回タイプするのは面倒です。

多くのシェルでは「エイリアス」を使ってこの問題を解決しますが、Fish Shell にはとても優れた機能があります。それが abbreviation(略して abbr) です。

生成AIやエージェントにコマンドライン操作を相談するときも、履歴(history)が読めると作業を説明しやすくなります。この記事では、私がエイリアスから abbr に移行した理由と、その設定を紹介します。

fishshell.com

abbr とは

abbr は、入力した短い文字列を長いコマンドに展開する機能です。たとえば gco と入力してスペースやエンターを押すと、自動的に git checkout に展開されます。

最大の特徴は、展開されたコマンドが入力行に表示されることです。スペースを押して展開すれば、実行前に内容を確認し、その場で編集できます。

abbr の圧倒的なアドバンテージ

これが最も重要なポイントです。2024年以降、共同作業や自動化ツールに加え、生成AIがターミナルワークを下支えするようになりました。そして、abbr はこの新しいワークスタイルに完璧にフィットします。

履歴から実行したコマンドが伝わる

例えば、昨日の作業をチームに共有するときです。

エイリアスの場合:

$ history | tail -20
gco feature-branch
gaa
gcm "Add new feature"
gp origin feature-branch

履歴を受け取った人は、gco や gaa がどのコマンドを実行するのか確認する必要があります。個人のローカル設定は共有されていないからです。

abbr の場合:

$ history | tail -20
git checkout feature-branch
git add --all
git commit -m "Add new feature"
git push origin feature-branch

誰が見ても即座に理解できます。ブランチを切り替え、全ての変更をステージングし、コミットしてプッシュしたのだとすぐ分かります。

実際の活用例

例1: デバッグ支援

# あなたのコマンド履歴(abbr を使用)
$ kubectl get pods --namespace production
$ kubectl logs pod-abc123 --namespace production
$ kubectl describe pod pod-abc123 --namespace production
$ kubectl get events --namespace production --sort-by='.lastTimestamp'

# 共有したい質問: "このエラーの原因を知りたい"

履歴を見た人は、どの対象にどの操作をしたのか確認できます。原因を調べるには実行結果やログも必要ですが、エイリアス(例:k、kgp、kl)の定義を説明する手間は省けます。

例2: ワークフローの自動化

# 毎日のデプロイ作業(abbr で記録された履歴)
$ docker compose build
$ docker compose down
$ docker compose up -d
$ docker compose logs --tail=100 web
$ curl https://example.com/health

# 「この手順をスクリプト化して」と頼むだけ

履歴をもとに、自動化する手順を整理できます。実際にスクリプトにする際は、途中の失敗への対応や実行環境も確認します。

例3: チームメンバーへの説明

# Slack や Issue に貼り付けるだけで伝わる
昨日のデプロイ手順:
$ git pull origin main
$ npm install
$ npm run build
$ docker compose build
$ docker compose up -d

abbr なら、エイリアスの定義を知らない相手にも元のコマンドを見せられます。

コマンド履歴が機械可読になる

生成AIの支援ツールに履歴を渡して相談する場合も、略称だけでは何を実行したか伝わりません。エイリアスの定義を別途説明する必要があります。

abbr なら、展開後のコマンドが履歴に残ります。エラーの原因や次の操作を相談するとき、相手が人でもAIでも、実行した操作を共有しやすくなります。

チーム開発での透明性

リモートペアプログラミングやスクリーンシェアで作業を共有する際です。

# あなた: この手順でデプロイします
$ dk build
$ dk up -d
$ dk logs -f

チームメイト: 「...何をしているのか分かりません」

abbr なら次のようになります。

$ docker compose build
$ docker compose up -d
$ docker compose logs -f

チームメイト: 「完璧に理解しました」

ドキュメントとしての履歴

あなたのコマンド履歴は、最高のドキュメントになります。例えば、kubectl でのデプロイ作業を考えてみましょう。

エイリアスの場合、履歴には k apply -f deployment.yaml、k get pods、k logs -f pod-name のように記録され、意味が分かりません。

abbr の場合は kubectl apply -f deployment.yaml、kubectl get pods、kubectl logs -f pod-name と記録されます。これなら、Wiki にコピペできますし、Issue にそのまま貼れます。解析ツールに渡して内容を振り返ってもらうこともでき、新しいチームメンバーの教材にもなります。

エイリアスの時代は終わった

はっきり言います。エイリアスは過去の遺物です。

少なくとも、画面や履歴を共有しながら作業する私には、略称のまま残す利点が見当たりません。入力は短く、表示と履歴は元のコマンドのまま。abbr を選ぶ理由は、この両立にあります。

エイリアスとの決定的な違い

エイリアス(Alias)の場合

alias gco="git checkout"
  • コマンド履歴には gco と記録される
  • 実際に何が実行されたか後から分からない
  • 他人と共有する際に説明が必要

abbr の場合

abbr --add gco "git checkout"
  • スペースキーを押すと git checkout が即座に展開される
  • コマンド履歴には展開後の git checkout が記録される
  • 履歴を検索する際に、エイリアスの短縮形ではなく実際のコマンドで検索できる
  • スクリーンショットやドキュメントにそのままコピペできる

abbr を使うべき理由

abbr の主なメリットは、コマンド履歴が検索しやすくなること、他者とコマンドを共有しやすくなること、そして実際に何が実行されるかが常に可視化されることです。

展開されたコマンドを毎回見るため、オプションを自然に覚えられる学習効果があります。history コマンドで過去のコマンドを見たとき、実際に何をしたかが一目瞭然です。同僚に「このコマンドを実行して」と伝える際、abbr で展開されたコマンドをそのまま共有できます。展開後に追加の引数を加えたり、一部を修正したりするのも簡単です。そして、abbr はインタラクティブシェルでのみ展開され、スクリプト内では展開されません。

基本的な使い方

abbr を追加する

abbr --add gst "git status"
abbr --add gaa "git add --all"
abbr --add gcm "git commit -m"

または、短縮形で表現できます。

abbr -a gst "git status"
abbr -a gaa "git add --all"
abbr -a gcm "git commit -m"

登録されている abbr を確認する

abbr --list
# または
abbr -l

abbr を削除する

abbr --erase gst
# または
abbr -e gst

すべての abbr を表示する

abbr --show
# または
abbr -s

実践的な abbr 設定例

私の実際の config.fish から、カテゴリ別に便利な abbr を紹介します。

ナビゲーション系

# ディレクトリ移動を快適に
abbr --add --global -- - 'cd -'           # 直前のディレクトリに戻る
abbr --add --global .. 'cd ..'            # 一つ上の階層へ
abbr --add --global ... 'cd ../..'        # 二つ上の階層へ
abbr --add --global .... 'cd ../../..'    # 三つ上の階層へ

Git 系(最も使用頻度が高い)

abbr --add --global g git
abbr --add --global ga 'git add'
abbr --add --global gaa 'git add --all'
abbr --add --global gc 'git commit -v'
abbr --add --global gcm 'git commit -m'
abbr --add --global gco 'git checkout'
abbr --add --global gcb 'git checkout -b'
abbr --add --global gp 'git push'
abbr --add --global gpl 'git pull'
abbr --add --global gst 'git status'
abbr --add --global gd 'git diff'
abbr --add --global gl 'git log'
abbr --add --global gf 'git commit --amend --no-edit'  # 直前のコミットを修正

Docker 系

abbr --add --global d docker
abbr --add --global dc 'docker compose'
abbr --add --global dcu 'docker compose up'
abbr --add --global dcd 'docker compose down'
abbr --add --global dps 'docker ps'

Kubernetes 系

abbr --add --global k kubectl
abbr --add --global kgp 'kubectl get pods'
abbr --add --global kgs 'kubectl get svc'
abbr --add --global kgd 'kubectl get deploy'

エディタ系

abbr --add --global v nvim
abbr --add --global vim nvim

高度な abbr の使い方

1. 旧来の --global オプション

abbr --add --global gst "git status"

この記事の設定例には、以前の書き方である --global が残っています。Fish 3.6以降では、abbr を universal 変数に保存する仕組みは廃止されました。新しく設定する場合は --global を付けず、abbr --add gst "git status" を config.fish に書けば十分です。公式ドキュメントでも、設定ファイルへの記述が案内されています。

2. --position anywhere - どこでも展開

デフォルトでは、abbr はコマンド名の位置で展開されます。これには行頭だけでなく、パイプに続くコマンド名も含まれます。--position anywhere を指定すると、引数の位置でも展開できます。次の例では、コマンドの後に入力した L をパイプごと展開します。

abbr -a L --position anywhere --set-cursor "% | less"

3. --set-cursor - カーソル位置の指定

展開後のカーソル位置を指定できます。% がカーソル位置のマーカーです。

abbr --add grepf --set-cursor 'grep -r "%" . | fzf'

grepf とタイプしてスペースを押すと grep -r "" . | fzf に展開され、カーソルが "" の中に配置されます。

4. --regex - 正規表現によるマッチング

パターンを正規表現で指定できます。たとえば、.txt で終わるファイル名を vim で開けます。

function vim_edit
    echo vim $argv
end

abbr -a vim_edit_texts --position command --regex ".+\.txt" --function vim_edit

5. --function - 関数による動的展開

関数を使って動的にコマンドを生成できます。bash の !! に相当する機能です。

function last_history_item
    echo $history[1]
end

abbr -a !! --position anywhere --function last_history_item

6. --command - 特定コマンドでのみ展開(Fish 4.0+)

Fish 4.0 以降では、特定のコマンドに対してのみ展開される abbreviation を作成できます。

abbr --add --command git co checkout

この場合、git co は git checkout に展開されますが、co 単独では展開されません。

config.fish への設定方法

Fish 3.6以降では、対話的に追加した abbr は現在のセッションで有効です。次回以降も使う設定は config.fish などの設定ファイルに記述します。そのファイルを dotfiles として管理すれば、別の環境にも持ち運べます。

推奨される設定方法

if status is-interactive
    # 既存の abbr をクリーンアップ(エラーを無視)
    abbr --erase gst 2>/dev/null
    abbr --erase gaa 2>/dev/null
    
    # 新しく abbr を追加
    abbr --add --global gst 'git status'
    abbr --add --global gaa 'git add --all'
    # ... 他の abbr
end

if status is-interactive で囲むことで、インタラクティブシェルでのみ abbr が定義されます。

--erase してから --add する理由

config.fish は新しいシェルを起動するたびに実行されます。既存の abbr を消してから追加することで、変更が確実に反映されます。

私の設定では、すべての abbr をまとめて消去してから再定義しています。

if status is-interactive
    # 既存のabbreviationをクリーンアップ(エラーを無視)
    abbr --erase -- - 2>/dev/null
    abbr --erase .. 2>/dev/null
    abbr --erase ... 2>/dev/null
    # ... すべての abbr を列挙
    
    # ナビゲーション
    abbr --add --global -- - 'cd -'
    abbr --add --global .. 'cd ..'
    # ... 新しく定義
end

よくある質問

abbr とエイリアスはどちらを使うべきか

A: 対話的な操作でコマンドを短く入力したいなら、私は abbr を勧めます。展開結果を確認・編集でき、履歴を共有するときにも略称の説明が要らないからです。

ただし、複雑な処理(条件分岐やパイプの組み合わせなど)が必要な場合は、関数を使いましょう。

abbr はスクリプトで使えるか

A: いいえ。abbr はインタラクティブシェルでのみ展開され、スクリプト内では展開されません。スクリプトでは関数やエイリアスを使ってください。

abbr を展開せずにスペースを入力したい場合

A: Ctrl+Space を押すと、abbr を展開せずにスペースを入力できます。

abbr を一時的に無効にしたいとき

A: 現在のセッションでは abbr --erase 名前 で削除できます。新しいセッションでも読み込ませたくない場合は、config.fish などにある定義も削除するか、コメントアウトしてください。

Fish 以外のシェルでも abbr を使う方法

「Fish に興味はあるけど、Zsh や Bash から移行するのは大変...」と感じる人も多いでしょう。

朗報です。abbr の恩恵は他のシェルでも受けられます。

Zsh で abbr を使う

Zsh には zsh-abbr という優れたプラグインがあります。Fish の abbr に完全にインスパイアされており、ほぼ同じ機能を提供します。他にも追加でいくつか類似ソフトウェアがあるので自分にあうものを選んでほしいです。

インストール方法

Homebrew を使う場合:

brew install olets/tap/zsh-abbr

インストール後に表示される読み込み設定も行います。手順は zsh-abbr の導入ガイド を参照してください。

Oh My Zsh に手動で追加する場合:

git clone https://github.com/olets/zsh-abbr.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-abbr

.zshrc の既存の plugins に zsh-abbr を追加します。以下の ... は他のプラグインを省略した表記です。

# プラグインとして読み込む
plugins=(... zsh-abbr)

使い方

# abbr を追加
abbr gco="git checkout"
abbr gst="git status"

# グローバル abbr(コマンド位置以外でも展開)
abbr -g L="| less"

# 一覧表示
abbr list

# 削除
abbr erase gco

Fish とほぼ同じシンタックスで使えます。

github.com

手動で実装する方法(軽量版)

プラグインを使わずに実装する試みが、以下のコードです。補完ウィジェットや既存のキーバインドにも依存するため、この断片だけで動く設定としては扱わず、利用中の Zsh 設定との組み合わせを確認する必要があります。

# 展開可能なエイリアスのリスト
typeset -a ealiases
ealiases=()

# abbr 風のエイリアス作成関数
function abbrev-alias() {
    alias $1
    ealiases+=(${1%%\=*})
}

# スペースキーでエイリアスを展開
function expand-ealias() {
    if [[ $LBUFFER =~ "\<(${(j:|:)ealiases})\$" ]]; then
        zle _expand_alias
        zle expand-word
    fi
    zle magic-space
}
zle -N expand-ealias

# スペースキーをバインド
bindkey ' ' expand-ealias
bindkey '^ ' magic-space  # Ctrl+Space で展開をスキップ

# Enter キーでも展開
expand-alias-and-accept-line() {
    expand-ealias
    zle .backward-delete-char
    zle .accept-line
}
zle -N accept-line expand-alias-and-accept-line

# abbr を定義
abbrev-alias gco="git checkout"
abbrev-alias gst="git status"
abbrev-alias gcm="git commit -m"

dev.to

Bash で abbr 風の機能を実装する

Bash には組み込みの abbr 機能はありませんが、bind コマンドを使って似たような動作を実現できます。

# スペースキーで展開される「abbr」を実装
bind '"\e[0n": " "'

# abbr のような関数
function abbr-expand() {
    local cmd="${READLINE_LINE%% *}"
    case "$cmd" in
        gco) READLINE_LINE="git checkout${READLINE_LINE#gco}" ;;
        gst) READLINE_LINE="git status${READLINE_LINE#gst}" ;;
        gcm) READLINE_LINE="git commit -m${READLINE_LINE#gcm}" ;;
    esac
}

# Space キーにバインド
bind -x '"\e[0n": abbr-expand'

ただし、この Bash の例は未完成です。コメントでは Space キーとしていますが、\e[0n はスペースそのものではなく、同じキー列への割り当ても重複しています。展開後のカーソル位置を調整する処理もありません。Bash の bind の仕様 に沿ってキーの割り当てなどを整える必要があり、このまま設定に追加しても説明どおりには動きません。すぐに abbr を使いたい場合、私は Zsh + zsh-abbr または Fish を勧めます。

どのシェルを選ぶべきか

abbr を標準機能として使いたいなら、Fish が候補になります。Zsh + zsh-abbr なら、既存の Zsh 環境を保ちながら略語展開を追加できます。Bash で自作する場合は、上の例で足りていない処理も実装する必要があります。

特に、共同作業や自動化が標準になった今では、abbr のようなトランスペアレントな機能が必須です。どのシェルを使うにしても、エイリアスから abbr への移行を強くお勧めします。

よくある質問(追加)

今使っている Zsh から Fish に移行すべきか

A: abbr だけが目的なら、zsh-abbr プラグインで十分です。ただし、Fish は他にも多くの優れた機能(シンタックスハイライト、自動補完など)を持っているので、試してみる価値はあります。

既存のエイリアスを abbr に移行するのは大変か

A: 単純なコマンドの略称から始めると移行しやすいです。Fish では abbr --add、Zsh の zsh-abbr では abbr で定義します。シェルごとの記法や引用符、どの位置で展開するかも確認してください。

まとめ

Fish Shell の abbr は、単なるショートカット以上の価値があります。変化の激しい開発環境において、abbr は必須のツールです。

abbr が提供する価値

abbr なら、短い入力から展開されたコマンドを確認し、必要に応じて編集できます。履歴にも実際のコマンドが残るので、後から自分で読み返すときも、チームや生成AIに相談するときも、何を実行したか伝えやすくなります。

エイリアスから abbr への移行

まずは、よく使うエイリアスを一つ abbr に移してみてください。履歴に元のコマンドが残るだけでも、使い勝手の違いが分かるはずです。

Fish では abbr --add で定義します。Zsh では zsh-abbr プラグインを導入して読み込み、その後に略語を定義します。

エイリアスの時代はおそらく終わる気がしています。それでもエイリアスのおかげで多くの時間を節約できたのは事実ですし、長く愛用してきた相棒でもあります。ありがとう、エイリアス。

参考リンク

github.com

github.com

dev.to

ddbeck.com


www.youtube.com