# 組込みコマンド

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

組込みコマンドの一覧は​目次を参照してください。

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

Yash の組込みコマンドは以下の種類に分けられます。

特殊組込みコマンドは最も重要な種類の組込みコマンドで、他の組込みコマンドとは異なる性質をいくつか持っています。まず、特殊組込みコマンドは対応する外部コマンドの存在に関係なく常に実行されます。また特殊組込みコマンドにおける変数代入の結果はコマンドの実行が終わった後も残ります。さらに POSIX 準拠モードでは、特殊組込みコマンドを実行する単純コマンド内でエラーが起きた場合、シェルが​対話モードでなければシェルは直ちに非 0 の終了ステータスで終了します。

必須組込みコマンドと​任意組込みコマンドは外部コマンドの存在に関係なく実行される点では特殊組込みコマンドと同様ですが、​関数で上書き可能な点が異なります。 必須組込みコマンドは常に利用可能ですが、任意組込みコマンドは POSIX では名前しか定義されていないため POSIX 準拠モードでは使えません。

拡張組込みコマンドは POSIX で言及されていないコマンドです。任意組込みコマンドと同様に、​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 準拠モードであるかどうかにかかわらず、ハイフン一つからなる引数 (`-`) は常にオペランドとみなされます。