単純コマンドは以下の手順に従って実行されます。
COMMAND_NOT_FOUND_HANDLER
変数が定義されていれば、コマンド eval -i "$COMMAND_NOT_FOUND_HANDLER"
が実行されます。ただしこのとき位置パラメータはコマンド名とコマンド引数に一時的に置き換えられます。またこのコマンドの実行中に定義されたローカル変数はこのコマンドの終了時に削除されます。このコマンドの実行時には HANDLED
ローカル変数が空文字列を値としてあらかじめ定義されます。このコマンドの実行後にこの変数の値が空文字列でなくなっていれば、このコマンドの終了ステータスがこの単純コマンドの終了ステータスとなり、コマンドが見つからなかったことはエラーとはみなされません。
単純コマンドで実行すべきコマンドは、展開で得られたコマンド名に基づいて以下の手順で特定されます。
/
) が含まれている場合は、それが実行すべき外部コマンドへのパス名であると特定されます。
PATH
変数の値に従って、実行すべき外部コマンドを検索しそのパス名を特定します。PATH
変数の値は、いくつかのディレクトリのパス名をコロン (:
) で区切ったものとみなされます。それらの各ディレクトリについて順に、ディレクトリの中にコマンド名と同じ名前の実行可能な通常のファイルがあるか調査します。そのようなファイルがあれば、そのファイルが実行すべき外部コマンドとして特定されます (ただし、コマンド名と同じ名前の組込みコマンドがあれば、代わりにその組込みコマンドが実行すべきコマンドとして特定されます)。どのディレクトリにもそのようなファイルが見つからなければ、実行すべきコマンドは見つからなかったものとみなされます。なお、空のディレクトリパス名はシェルの作業ディレクトリを表しているものとみなされます。
外部コマンドの検索が成功しパス名が特定できた場合、そのパス名が絶対パスならば、シェルはそのパス名を記憶し、再び同じコマンドを実行する際に検索の手間を省きます。ただし、再びコマンドを実行しようとした際に、記憶しているパス名に実行可能ファイルが見当たらない場合は、検索をやり直します。シェルが記憶しているパス名は hash 組込みコマンドで管理できます。
シェルは、入力が終わりに達して全てのコマンドを解釈・実行し終えた時や、exit 組込みコマンドを実行したときなどに終了します。シェルの終了ステータスは、シェルが最後に実行したコマンドの終了ステータスを 256 で割った余りです (一つもコマンドを実行しなかったときは 0)。
Trap 組込みコマンドでシェル終了時のハンドラが登録されている場合は、シェルが終了する直前にそのハンドラが実行されます。ただしこのハンドラ内で実行したコマンドはシェルの終了ステータスには影響しません。
対話モードでないシェルの実行中に下記エラーが発生した場合、シェルは直ちに終了します。このときシェルの終了ステータスは非 0 です。
注: Yash はそうではありませんが、実行すべきコマンドが見つからなかったときに直ちに終了するようなシェルもあります。
関数は一つの複合コマンドを単純コマンドのように呼び出せるようにする機構です。関数は関数定義コマンドによって定義でき、単純コマンドによって実行できます。関数を削除するには unset 組込みコマンドを使います。
Yash には、シェルの起動時に最初から定義されている関数は一つもありません。
関数の実行は、関数の内容である複合コマンドを実行することによって行われます。関数の実行中は、関数の引数が位置パラメータになります。それまでの位置パラメータは一時的に使えなくなりますが関数の実行が終わった時に元の位置パラメータに戻ります。
ローカル変数とは、関数の実行中にだけ有効な一時的な変数です。ローカル変数は typeset 組込みコマンドを使って作ることができます。関数の実行中に作られたローカル変数は関数の実行が終わった時に削除され、ローカル変数を作る前の元の変数の状態に戻ります。
関数の実行中でないときにローカル変数を作ることはできません。ローカル変数を作ろうとしても、通常の変数になります。
シェルは実行時に以下の情報を保持します。これらの情報はシェルが起動されたときに元のプログラムからシェルに受け継がれます。そしてシェルが起動する外部コマンドやサブシェルにもシェルから受け継がれます。
これらの情報は所定の組込みコマンド等を使って変更可能です。
サブシェルは、実行中のシェルのプロセスのコピーです。サブシェルは括弧 ( )
で囲んだグルーピングやパイプラインで使われます。
サブシェルはシェルのプロセスのコピーであるため、上記の情報の他にシェルで定義された関数やエイリアスなどの情報も元のシェルから受け継ぎます。ただし、
無視のものを除き) サブシェルではすべて解除されます。
サブシェルは元のシェルとは独立しているため、サブシェルでの作業ディレクトリの変更や変数代入は元のシェルに影響しません。