【Linux】aliasの使い方|.bashrcへの永続化とスクリプトで効かない罠

【Linux】aliasの使い方|.bashrcへの永続化とスクリプトで効かない罠 Linux

aliasは、長いコマンドに短い別名をつけるためのシェルの機能です。alias ll='ls -la'と登録しておけば、llと打つだけでls -laが実行されます。よく使うオプション付きコマンドを毎回タイプする手間を省ける、地味だが効果の大きい時短ツールです。

ただし、aliasには意外と知られていない、そして誤解されやすい仕様があります。それが「シェルスクリプトの中では、既定でaliasが展開されない」ことです。しかも、この制約は「別のスクリプトを呼んだときだけ」ではなく、同じスクリプトの中で定義したaliasを、同じスクリプトの後続行で使おうとしても効きません。この記事では、実機のLinux(WSLのDebian)でこの現象を実際に再現しながら、aliasの基本と落とし穴を整理します。

先に結論

  • 基本はalias 名前='コマンド'。以降、名前と打つだけで実行されます。
  • aliasだけで一覧表示、unalias 名前で削除します。
  • ターミナルを閉じると消えるため、永続化するには~/.bashrcに書く必要があります。
  • シェルスクリプトの中では、既定でaliasは展開されません(同じスクリプト内で定義しても同様)。
  • スクリプトでもaliasを使いたいときはshopt -s expand_aliasesを先頭に書きます。
  • 一時的にaliasを無視して本来のコマンドを使うには\コマンドcommand コマンドを使います。

永続化に使う~/.bashrcの仕組みは環境変数とPATHの記事、コマンドの実体を調べる方法は同記事のwhichもあわせて参考になります。

スポンサーリンク

aliasの基本:作成・一覧・削除

alias 名前='コマンド'で登録します。以降、そのターミナルでは名前と打つだけでコマンドが実行されます。

alias の基本操作
# 別名を登録する
alias ll='ls -la'
ll /tmp
# → ls -la /tmp と同じ結果になる

# 登録済みの alias を一覧表示
alias
# alias ll='ls -la'
# ...

# 特定の alias だけ確認
alias ll

# alias を削除する
unalias ll
ll
# bash: ll: command not found  ← 削除後は使えない

実機でも、alias ll='ls -la'を登録するとllコマンドが正しくls -laとして動作し、alias単体で登録済みの一覧(alias ll='ls -la'という形式)が確認できました。unalias llで削除すると、以降llbash: ll: command not foundとなり、通常のコマンドと同じ扱いで「見つからない」エラーになります。aliasはコマンドではなくシェル自身が持つ機能であり、その場限りの登録です。

永続化:.bashrcに書く

aliasはそのままだとターミナルを閉じると消えてしまいます。毎回使いたいaliasは、~/.bashrc(bashの設定ファイル)に書いて永続化します。

~/.bashrc への永続化
# ~/.bashrc の末尾に追記する
echo "alias ll='ls -la'" >> ~/.bashrc
echo "alias gs='git status'" >> ~/.bashrc

# 変更を今のシェルに反映(再ログインなしで有効化)
source ~/.bashrc

# 以降、新しく開いたターミナルでも ll・gs が使える

~/.bashrcaliasの行を追記しておけば、新しく開いたターミナルすべてで自動的に有効になります。編集後にすぐ試したいときはsource ~/.bashrcで今のシェルに反映させます(新しいターミナルを開けば自動的に読み込まれるので、sourceは「今すぐ試したい」ときの手段です)。git statusdocker composeのような長いコマンドこそ、aliasの恩恵が大きいところです。

【最重要】シェルスクリプトの中では展開されない

ここがaliasで最も誤解されやすいポイントです。シェルスクリプト(非対話的に実行されるシェル)の中では、既定でaliasが展開されません。しかも、「別のスクリプトから呼び出したときだけ」ではなく、同じスクリプトの中で定義したaliasを、同じスクリプトの後続行で使おうとしても効きません

同じスクリプト内でも効かない(再現)
# testscript.sh の中身
#!/bin/bash
alias greet='echo Hello from alias'
greet

# 実行すると…
bash testscript.sh
# testscript.sh: line 3: greet: command not found
#   ↑ 直前の行で定義したはずの alias が使えない!
同じスクリプト内でもcommand not found(実証)

実機で、alias greet='echo Hello from alias'と定義した直後の行greetを呼び出すスクリプトを実行したところ、testscript.sh: line 3: greet: command not foundというエラーになりました。対話的なターミナルで同じコマンドを打てば問題なく動くのに、.shファイルとして実行すると効かないのです。これは、bashが「非対話シェルではaliasを展開しない」という仕様を持っているためで、たとえaliasgreetが同じファイル・同じシェルプロセスの中にあっても関係ありません。「ターミナルでは動くのにスクリプトにしたら動かない」の原因がaliasだった、というのは実はよくある落とし穴です。スクリプトで再利用したい処理は、aliasではなくシェル関数(function() { ... }にするのが本来の解決策です。

それでも、どうしてもスクリプト内でaliasを使いたい場合は、shopt -s expand_aliasesをスクリプトの先頭(alias定義より前)に書くことで展開が有効になります。

shopt -s expand_aliasesで有効化
#!/bin/bash
shopt -s expand_aliases   # これを先頭に書く

alias greet='echo Hello from alias'
greet
# Hello from alias   ← 今度は正しく実行される

実機でも、shopt -s expand_aliasesを先頭に追加したスクリプトでは、greetが正しくHello from aliasを出力しました。ただし、この方法はあくまで応急処置です。スクリプトの保守性・可読性を考えると、繰り返し使う処理は最初からシェル関数として書くほうが素直で、多くのシェルスクリプトのスタイルガイドでも関数が推奨されています。

aliasを一時的に無視する(\command / command)

逆に、aliasが設定されていても、そのときだけ本来のコマンドを使いたい場合があります。\コマンド(先頭にバックスラッシュ)やcommand コマンドを使うと、aliasをバイパスできます。

aliasのバイパス
alias ls='echo INTERCEPTED'

ls /tmp
# INTERCEPTED   ← alias が効いている

\ls /tmp
# (本来の ls の結果。バックスラッシュでaliasを無視)

command ls /tmp
# (こちらも本来の ls の結果)

実機でも、lsecho INTERCEPTEDにaliasしている状態で、\lscommand lsを使うと、aliasを無視して本来のlsコマンドが実行されることを確認しました。特に他人の環境や共用サーバーで、予期しないaliasが設定されている(rmrm -iにaliasされているなど)ときに、「本来のコマンドの挙動を確認したい」場面で役立ちますcommandのほうが、シェル関数まで含めてバイパスできるためより確実です。

typeでaliasかどうかを判定する

「このコマンドはaliasなのか、それとも普通のコマンドなのか」を調べるにはtypeを使います。

type での判別
alias mycmd='echo test'

type mycmd
# mycmd is aliased to `echo test'

type ls
# ls is /usr/bin/ls   ← 実体のあるコマンド

実機でも、type mycmdmycmd is aliased to ...とaliasであることを明示し、type ls(alias化していない状態)はls is /usr/bin/lsという実体のパスを返しました。「なぜか思った挙動と違う」というときに、type コマンド名aliasなのか、関数なのか、実体のあるコマンドなのかを切り分けるのが調査の第一歩です。

主な書き方一覧

aliasの要点をまとめます。

書き方 働き
alias 名前='コマンド' 別名を登録
alias 登録済みの一覧を表示
unalias 名前 別名を削除
~/.bashrcに追記 永続化(新規ターミナルで自動有効)
\コマンド / command コマンド aliasを無視して本来のコマンドを実行
type 名前 alias・関数・実体コマンドの判別

よくある失敗

スクリプトの中でaliasがcommand not foundになる

非対話シェルでは既定でaliasが展開されません。shopt -s expand_aliasesを使うか、シェル関数に書き換えます。

aliasを登録したのに次回のターミナルで消えている

その場限りの登録です。~/.bashrcに書いて永続化します。

他人のaliasに気づかず予想外の動作をする

type コマンド名で確認し、必要なら\コマンドcommand コマンドで本来の動作にできます。

alias名と既存コマンド名を混同する

lsなど既存コマンドと同じ名前でaliasすると、意図を忘れて混乱の元になります。

複雑な処理をaliasに詰め込む

条件分岐や引数処理が必要な処理は、aliasではなくシェル関数にすべきです。

よくある質問

Qaliasはどうやって作りますか?
Aalias 名前='コマンド'のように書きます。たとえばalias ll='ls -la'とすれば、以降llと打つだけでls -laが実行されます。ただしその場限りの登録なので、ターミナルを閉じると消えます。恒久的に使いたい場合は~/.bashrcに書いてください。
Qシェルスクリプトの中でaliasを使うとcommand not foundになります。
Aシェルスクリプト(非対話シェル)では、既定でaliasが展開されないためです。実機でも、同じスクリプト内で定義したaliasを直後の行で使おうとしてもcommand not foundになることを確認しています。対処法は、スクリプトの先頭にshopt -s expand_aliasesを書くか、そもそもaliasではなくシェル関数として定義することです。
Qaliasを消すには?
Aunalias 名前を使います。実機でも、削除後にそのコマンドを実行するとcommand not foundになる(元のコマンドとしての実体もない場合)ことを確認しています。すべてのaliasを一括で消したい場合はunalias -aが使えます。
Qaliasを一時的に無視して本来のコマンドを使うには?
A\コマンド(バックスラッシュを先頭に付ける)またはcommand コマンドを使います。実機でも、lsをaliasで上書きしている状態で、\lscommand lsが本来のlsの結果を返すことを確認しています。予期しないaliasが設定されている環境で本来の挙動を確認したいときに便利です。
Qそのコマンドがaliasかどうか調べるには?
Atype コマンド名を使います。aliasの場合は「〜 is aliased to …」、シェル関数の場合は「〜 is a function」、実体のあるコマンドの場合はそのパス(例: 「ls is /usr/bin/ls」)が表示されます。実機でもこの3種類の判別ができることを確認しています。

まとめ

  • alias 名前='コマンド'で登録、unaliasで削除、~/.bashrcで永続化します。
  • シェルスクリプトの中では既定でaliasが展開されません(同じスクリプト内でも同様)。
  • スクリプトで使いたいならshopt -s expand_aliases、本来はシェル関数を使うのが素直です。
  • \コマンド/command コマンドでaliasを一時的にバイパスできます。
  • type コマンド名で、alias・関数・実体コマンドを判別できます。

aliasは、日常の対話的な作業を効率化する便利な機能ですが、「スクリプトの中では効かない」という制約を知らないと思わぬところでつまずきます。対話シェル専用の時短ツールと割り切り、スクリプトで再利用したい処理はシェル関数として書く——この使い分けを押さえておけば、aliasを安心して活用できます。