コマンド名とそのコマンドの引数で構成されるコマンドが実行される場合、以下の処理によってコマンドが実行されます。
- コマンド名に<slash>が含まれない場合、シェルは関数を探し、存在する場合はその関数を実行します。
- 関数と一致しない場合、組み込みコマンドを検索し、存在する場合はその組み込みコマンドを実行します。
- 名前が関数でも組み込みコマンドでもなく、スラッシュも含まれていない場合、PATH内を検索し実行可能ファイルを探します。見つからない場合は、command_not_found_handle関数を探し、それがなければエラーメッセージを表示します(終了ステータス127)。また、コマンドの検索が成功した場合はその実行可能ファイルの場所を記録し、複数回のPATH検索を避けます。
- 成功するか、スラッシュが含まれている場合、指定したプログラムを実行します。
- 実行できない場合、シェルスクリプトと仮定し実行します。
- 非同期でない場合、コマンドの終了を待ち、終了ステータスを収集します。
command_not_found_handle関数について、例えば、Ubuntu23.10でシェルを起動したときに定義されている関数を確認してみると以下のようになっています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$ declare -f -p command_not_found_handle command_not_found_handle () { if [ -x /usr/lib/command-not-found ]; then /usr/lib/command-not-found -- "$1"; return $?; else if [ -x /usr/share/command-not-found/command-not-found ]; then /usr/share/command-not-found/command-not-found -- "$1"; return $?; else printf "%s: command not found\n" "$1" 1>&2; return 127; fi; fi } |
コマンドが失敗したときの詳しい表示は別のファイルで実装され、その別のファイルが実行できない場合、printf文で簡素なエラーメッセージが表示されます。