typeコマンドでシェル組み込みと外部コマンドを区別する方法|whichとの違いやalias確認も

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Linuxtips, シェルスクリプト > typeコマンドでシェル組み込みと外部コマンドを区別する方法|whichとの違いやalias確認も
「このコマンドはどこにあるんだろう?」と思って which を打ったら何も出てこない——そんな経験はないでしょうか。
実は which が見つけられないコマンドが存在します。シェル組み込みコマンド(built-in)と呼ばれる種類です。

この記事では、type コマンドの使い方を解説します。コマンドがシェル組み込みなのか、外部バイナリなのか、エイリアスなのかを一発で判別できるようになります。シェルスクリプトのデバッグや、予期しない動作の原因調査にも役立ちます。

この記事のポイント

・type コマンドでシェル組み込み・外部コマンド・alias を即座に判別できる
・which が何も返さない場合は type で確認するのが正しい手順
・type -a で同名コマンドの全候補をまとめて確認できる
・スクリプトのデバッグや意図しない動作の原因特定に実務で頻繁に使う


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
図解60P/登録10秒/解除も3秒 / 詳細はこちら

なぜ which だけでは不十分なのか

Linux のコマンドには大きく3種類あります。

シェル組み込みコマンド(built-in):bash 自身が処理する。ファイルとして存在しない
外部コマンド:/usr/bin/ や /sbin/ 配下に実行ファイルが存在する
エイリアス(alias):ユーザーが定義した別名。設定ファイルや対話シェルで定義される

which コマンドは「外部コマンドのファイルパスを探す」ツールです。シェル組み込みコマンドはファイルとして存在しないため、which では何も返ってきません。

# which cd を実行しても何も返ってこない $ which cd $ # type なら正確に教えてくれる $ type cd cd is a shell builtin

cd がなぜ which で見つからないか不思議に思ったことがあるなら、まさにこの違いが理由です。

type コマンドの基本的な使い方

1. コマンドの種類を確認する

type コマンドは bash の組み込みです。引数にコマンド名を指定するだけで動作します。

# 書式 type コマンド名 # シェル組み込みコマンドの例 $ type cd cd is a shell builtin $ type echo echo is a shell builtin $ type pwd pwd is a shell builtin

シェル組み込みコマンドは bash が直接処理するため、外部プロセスを生成しません。これがスクリプト内で高速に動作する理由の一つです。

2. 外部コマンドのパスを確認する

外部コマンドの場合は、実行ファイルのフルパスが表示されます。

# 外部コマンドの確認 $ type ls ls is /usr/bin/ls $ type grep grep is /usr/bin/grep $ type python3 python3 is /usr/bin/python3 $ type nginx nginx is /usr/sbin/nginx

これは which コマンドと同じ情報です。ただし type は組み込みコマンドやエイリアスも含めて一元的に確認できます。

3. エイリアスの確認

多くの環境では llla がエイリアスとして定義されています。type で確認するとエイリアスの中身まで表示されます。

# エイリアスの確認 $ type ll ll is aliased to 'ls -l --color=auto' $ type la la is aliased to 'ls -A' # alias を自分で定義した場合 $ alias mygrep='grep --color=always' $ type mygrep mygrep is aliased to 'grep --color=always'

スクリプト内でコマンドが意図通りに動かない場合、alias が割り込んでいることがあります。type で確認するのが最初のステップです。

応用・実務での使い方

1. type -a で全候補を一覧表示する

同じ名前のコマンドが複数の場所に存在する場合があります(外部コマンドとシェル組み込みが両方ある、など)。type -a を使うとすべての候補を表示できます。

# echo は組み込みと外部コマンドの両方が存在する $ type -a echo echo is a shell builtin echo is /usr/bin/echo # pwd も同様 $ type -a pwd pwd is a shell builtin pwd is /usr/bin/pwd # ls はエイリアス + 外部コマンドが両方ある場合 $ type -a ls ls is aliased to 'ls --color=auto' ls is /usr/bin/ls

-a オプションは、スクリプト内でどのコマンドが実際に呼ばれているのかを明確にしたい場合に役立ちます。シェルは上から順に優先します(エイリアス > 組み込み > 外部コマンド)。

2. type -t でコマンドの種類を文字列で取得する

スクリプト内でコマンドの種類を条件分岐に使いたい場合は type -t が便利です。aliasbuiltinfilefunction のいずれかを返します。

# type -t の出力例 $ type -t cd builtin $ type -t ls alias $ type -t grep file $ type -t myfunc function # スクリプト内での活用例 CMD="some_command" KIND=$(type -t "$CMD" 2>/dev/null) if [ "$KIND" = "file" ]; then echo "${CMD} は外部コマンドです" elif [ "$KIND" = "builtin" ]; then echo "${CMD} はシェル組み込みです" else echo "${CMD} が見つかりません" fi

3. シェル関数の確認

type はシェル関数も認識します。関数が定義されているかどうかをスクリプトから確認したい場合に使います。

# シェル関数を定義する $ myfunc() { echo "hello from myfunc"; } # type で確認すると関数の中身が表示される $ type myfunc myfunc is a function myfunc () { echo "hello from myfunc" }

関数の中身まで確認できるのは type の強みです。declare -f myfunc と同様の情報が得られます。

4. コマンドが存在するかをチェックする

スクリプト内で外部コマンドのインストール確認をする場合、command -vtype のどちらかを使います。type -P は外部コマンドのパスのみを返し、組み込みは無視します。

# type -P で外部コマンドのパスのみ返す(POSIX準拠環境では command -v が推奨) $ type -P nginx /usr/sbin/nginx $ type -P cd # 何も返さない(組み込みのため) # インストール確認スクリプトの例 if type -P git > /dev/null 2>&1; then echo "git はインストール済みです" else echo "git が見つかりません。インストールしてください" fi

トラブルシュート・よくある疑問

「command not found」なのに which では見つかる?

which はコマンドが PATH 上に存在するかを確認するだけで、実行できるかどうかは別問題です。
実行ファイルのパーミッションが 0 や 600 になっていて実行できない場合でも、which ではパスが返ります。

# パーミッションが実行不可の場合 $ ls -l /usr/local/bin/myscript -rw-r--r-- 1 root root 512 Apr 24 10:00 /usr/local/bin/myscript $ which myscript /usr/local/bin/myscript # パスは返ってくる $ myscript bash: /usr/local/bin/myscript: Permission denied # でも実行できない # chmod で実行権を付ける $ sudo chmod 755 /usr/local/bin/myscript

パーミッションのトラブルに遭遇したら Linux 基本コマンドの解説 も合わせて確認してください。

alias が意図せず上書きしている場合の対処

rmrm -i にエイリアスされていて、スクリプト内で確認なしに削除したいのに確認が出てしまう——これはよくあるトラブルです。

# エイリアスを確認する $ type rm rm is aliased to 'rm -i' # スクリプト内でエイリアスを無視して外部コマンドを直接呼ぶ場合 # コマンド名の前にバックスラッシュを付ける \rm -rf /tmp/work_dir # または command コマンドを使う command rm -rf /tmp/work_dir

PATH の順序が影響するケース

同名のコマンドが複数の場所に存在する場合、シェルは PATH の左から順に探して最初に見つかったものを実行します。type -a で優先順位を把握しておくと、予期しない動作を防げます。

# 現在の PATH を確認 $ echo $PATH /usr/local/bin:/usr/bin:/bin:/sbin # python3 がどこにあるか全候補確認 $ type -a python3 python3 is /usr/local/bin/python3 python3 is /usr/bin/python3 # /usr/local/bin が先にあるため、そちらが優先される

csh での環境変数設定の解説 も参考にしてください。環境変数 PATH の仕組みを理解すると、コマンドの優先順位が直感的にわかるようになります。

which との使い分けまとめ

やりたいこと コマンド 組み込み対応
コマンドの種類を確認する type コマンド名 あり
外部コマンドのパスを確認する which コマンド名 または type -P コマンド名 なし(which)/ なし(type -P)
同名コマンドの全候補を表示する type -a コマンド名 あり
コマンド種別を文字列で取得する type -t コマンド名 あり
コマンドが存在するか確認する(スクリプト向け) command -v コマンド名 あり(POSIX準拠)
ls コマンドの基本オプション のような外部コマンドは which でも確認できますが、シェル組み込みやエイリアスが絡む場合は必ず type を使う——と習慣づけておくと、デバッグの手間が減ります。

本記事のまとめ

確認したいこと コマンド
コマンドがシェル組み込みか外部コマンドかを調べる type コマンド名
エイリアスの定義内容を確認する type コマンド名
同名コマンドの全候補と優先順位を確認する type -a コマンド名
コマンド種別を文字列で取得する(スクリプト内条件分岐) type -t コマンド名
外部コマンドのパスのみを返す type -P コマンド名
シェル関数の定義内容を確認する type 関数名

typeコマンドで一歩進んだ。次はLinux全体の仕組みを体系的に押さえませんか?

シェルの動作を理解することはLinux習熟の核心です。ネットの断片情報をつなぎ合わせるだけでは、現場でのトラブルに太刀打ちできません。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。

「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

登録10秒/合わなければ解除3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として15年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。