Description: Yash の組込みコマンドに関する共通の事柄について

# 組込みコマンド

組込みコマンドとはシェルに内蔵されたコマンドです。組込みコマンドは外部のプログラムを起動することなくシェル自身によって実行されます。

## 組込みコマンドの種類

Yash の組込みコマンドは特殊組込みコマンド・準特殊組込みコマンド・通常の組込みコマンドの三種類に分けられます。

特殊組込みコマンドは他の組込みコマンドよりも特に重要なコマンドで、他のコマンドとは異なる性質をいくつか持っています。まず、特殊組込みコマンドは対応する外部コマンドの存在に関係なく常に実行されます。また特殊組込みコマンドにおける変数代入の結果はコマンドの実行が終わった後も残ります。さらに POSIX 準拠モードでは、特殊組込みコマンドにおいてリダイレクトエラーまたは代入エラーが発生した場合あるいはコマンドのオプションやオペランドの使い方が間違っている場合、シェルが対話モードでなければシェルは直ちに非 0 の終了ステータスで終了します。

準特殊組込みコマンドは特殊組込みコマンドに次いで重要な組込みコマンドで、対応する外部コマンドの存在に関係なく常に実行されます。その他の点では準特殊組込みコマンドは通常の組込みコマンドと同じです。

外部コマンドとして実装可能な組込みコマンドや POSIX に規定されていない組込みコマンドを含む、重要度の低い組込みコマンドは通常の組込みコマンドです。POSIX 準拠モードでは、通常の組込みコマンドは対応する外部コマンドが `PATH` 変数の検索で見つかった場合のみ実行されます。

## コマンドの引数の構文

ここでは組込みコマンドの引数に関する一般的な規則について説明します。Yash の組込みコマンドの引数の指定・解釈の仕方は、他に断りがない限りこの規則に従います。

コマンドの引数は、オプションとオペランドの二種類に分けられます。オプションはハイフン (`-`) で始まる引数で、主にコマンドの動作を変更するのに使われます。オプションの中にはそれに対応する引数をとるものもあります。オペランドはオプション以外の引数で、主にコマンドが処理を行う対象を指定するのに使われます。

一つのコマンドに複数のオプションを与える場合、原則としてそれらのオプションの順序はコマンドの動作に影響しません。しかしオペランドの順序には意味があります。

オプションには一文字のオプションと長いオプションとがあります。一文字のオプションは英数字一文字によって識別されるオプションです。長いオプションはもっと長い文字列によって識別されるオプションです。POSIX 規格は一文字のオプションについてしか規定していないため、POSIX 準拠モードでは長いオプションは使えません。

一文字のオプションは、一つのハイフンと一文字の英数字からなります。例えば `-a` は一文字のオプションです。引数をとるオプションでは、コマンドに与えられた引数の並びの中でそのオプションの直後に位置している引数がそのオプションに対する引数とみなされます。

例 1. Set 組込みコマンドと一文字のオプション

Set 組込みコマンドにおいて、`-m` は引数をとらない一文字のオプション、`-o` は引数をとる一文字のオプションです。

- `set -o errexit -m`

- `set -oerrexit -m`

この二つの例では、`errexit` が `-o` オプションに対する引数となります。

上の二つ目の例では、`-o` オプションとそれに対する引数が一つのコマンドライン引数になっています。POSIX はこのような書き方は避けなければならないと定めており、POSIX に従うアプリケーションは必ず一つ目の例のようにオプションとそれに対する引数を別々のコマンドライン引数として与えなければなりません。しかし yash はどちらの指定の仕方も受け付けるようになっています。

引数をとらない複数の一文字のオプションは、一つにまとめて書くことができます。例えば `-a`, `-b`, `-c` という三つのオプションは `-abc` と書けます。

長いオプションは、二つのハイフンとオプション名を表す文字列からなります。例えば `--long-option` は長いオプションです。オプション名は他と紛らわしくない限り末尾を省略できます。例えば他に `--long` で始まる長いオプションがなければ、`--long-option` は `--long` と省略できます。引数をとるオプションでは、一文字のオプションの場合と同様に、オプションの直後にあるコマンドライン引数がそのオプションに対する引数とみなされます。あるいは、オプション名の後に等号 (`=`) で区切って直接引数を与えることもできます。

例 2. Fc 組込みコマンドと長いオプション

Fc 組込みコマンドにおいて、`--quiet` は引数をとらない長いオプション、`--editor` は引数をとる長いオプションです。

- `fc --editor vi --quiet`

- `fc --editor=vi --quiet`

この二つの例では、`vi` が `--editor` オプションに対する引数となります。

オプション (およびオプションに対する引数) 以外の引数は、全てオペランドとみなされます。POSIX は、オペランドは全てオプションより後に書かなければならないと定めています。そのため POSIX 準拠モードでは、最初のオペランドより後にある引数は (たとえそれがオプションであるように見えても) 全てオペランドとして解釈します。POSIX 準拠モードでないときは、オペランドの後にオプションを書いても構いません。

POSIX 準拠モードであるかどうかにかかわらず、ハイフン二つからなる引数 (`--`) はオプションとオペランドとの区切りとして使えます。この区切り以降の全てのコマンドライン引数はオペランドとして解釈されるため、ハイフンで始まるオペランドを正しく指定できます。

例 3. Set 組込みコマンドのオプションとオペランド

- `set -a -b -- -c -d`

この例では、`-a` と `-b` がオプションで、`-c` と `-d` がオペランドとなります。区切り (`--`) 自体はオプションでもオペランドでもありません。

POSIX 準拠モードであるかどうかにかかわらず、ハイフン一つからなる引数 (`-`) は常にオペランドとみなされます。