SEARCH
NEW RPMS
DIRECTORIES
ABOUT
FAQ
VARIOUS
BLOG
DONATE


YUM REPOSITORY

 
 

MAN page from Fedora 26 yash-2.47-1.fc26.x86_64.rpm

YASH

Section: \ \& (1)
Updated: 2018-04-10
Index 

名前

yash - POSIX 準拠コマンドラインシェル 

書式

yash [オプション...] [--] [オペランド...] 

はじめに

Yet another shell (yash) は Unix 系 OS 用コマンドラインシェルです。POSIX.1-2008 規格に (一部の例外を除いて) 準拠しています。POSIX 準拠を謳う他のシェルよりも精確な準拠を目指しています。また、コマンド履歴やコマンドライン編集など、対話シェルとして標準的な機能も備えています。

このプログラムは GNU General Public License (Version 2) の元で自由に再配布・変更などができます。ただし、プログラムの利用は全て各自の自己責任の下で行っていただくことになります。作者はプログラムの瑕疵に対して一切責任を取りません。また、このマニュアルはクリエイティブ・コモンズの表示-継承 2.1 日本ライセンスの下で自由に再配布・変更などができます。

Yash は渡邊裕貴 (通称まじかんと) という一人の開発者によって開発されています。Yash の開発プロジェクトおよび ホームページは OSDN がホストしています。 

シェルの起動

Yash がプログラムとして起動されると、yash はいくつかの初期化処理を行った後、コマンドを読み取って実行する処理に移ります。これらの処理の内容は、主に起動時のコマンドライン引数によって決まります。 

起動時のコマンドライン引数

Yash の起動時のコマンドライン引数は POSIX に準拠しています。POSIX で定められているとおり、引数は オプションオペランド に分類されます。引数の書式に関する一般的な説明についてはコマンドの引数の構文を参照してください。オプションはオペランドより前に指定する必要があります。

オプションに -c (--cmdline) オプションが含まれている場合、オペランドを少なくとも一つ与える必要があります。シェルは、この最初のオペランドをコマンドとして解釈・実行します。二つ目のオペランドがある場合は、特殊パラメータ 0 がそれに初期化されます。三つ目以降のオペランドは、位置パラメータになります。 -c (--cmdline) オプションを指定した場合は、ファイルや標準入力からコマンドを読み込むことはありません (ドット組込みコマンドを使用したときを除く)。

オプションに -s (--stdin) オプションが含まれている場合、シェルは標準入力から一行ずつコマンドを読み取って、解釈・実行します。オペランドはすべて位置パラメータの初期化に使われます。特殊パラメータ 0 はこのシェルが起動されたときに元のプログラムから受け取った最初の引数に初期化されます。

-c (--cmdline) オプションも -s (--stdin) オプションも指定されなかった場合は、シェルはファイルからコマンドを読み取って解釈・実行します。最初のオペランドが読み込むファイル名と見なされ、特殊パラメータ 0 の値となります。残りのオペランドは位置パラメータになります。オペランドが一つもない場合は、 -s (--stdin) オプションを指定したときと同様に標準入力からコマンドを読み込みます。

-c (--cmdline) オプションと -s (--stdin) オプションを同時に使用することはできません。

--help オプションまたは -V (--version) オプションが指定されている場合は、通常の初期化処理やコマンドの解釈・実行は一切行いません。それぞれシェルのコマンドライン引数の簡単な説明とバージョン情報を標準出力に出力した後、そのままシェルは終了します。 -V (--version) オプションを -v (--verbose) オプションと共に使用すると、シェルで利用可能な機能の一覧も出力されます。

-i (--interactive) オプションが指定されている場合、シェルは対話モードになります。逆に +i (++interactive) オプションが指定されている場合、シェルは対話モードになりません。

-l (--login) オプションが指定されている場合、シェルはログインシェルとして動作します。

--noprofile, --norcfile, --profile, --rcfile 各オプションは、シェルの初期化処理の動作を指定します (後述)。

その他のオプションとして、set 組込みコマンドで指定可能な各種オプションをシェルの起動時に指定することができます。(+ で始まるオプションを含む)

最初のオペランドが - であり、かつオプションとオペランドが -- で区切られていない場合、そのオペランドは特別に無視されます。 

シェルの初期化処理

シェルの初期化処理は以下のように行われます。

1.Yash はまず、(コマンドライン引数の前に渡される) それ自身の起動時の名前を解析します。その名前が-で始まる場合は、シェルはログインシェルとして動作します。また名前がshである場合 (/bin/shのようにshで終わる場合を含む) は、シェルはPOSIX 準拠モードになります。

2.オペランドが一つもなく、かつ標準入力と標準エラーがどちらも端末ならば、シェルは自動的に対話モードになります。ただし+i(++interactive) オプションが指定されている場合はそちらを優先します。

3.対話モードのシェルでは自動的にジョブ制御が有効になります。ただし+m(++monitor) オプションが指定されている場合はそちらを優先します。

4.シェルは以下の初期化スクリプトを読み込んで解釈・実行します。(ただしシェルプロセスの実ユーザ ID と実効ユーザ ID が異なっているか、実グループ ID と実効グループ ID が異なっている場合を除く)

1.シェルがログインシェルとして動作している場合は、--profile=ファイル名オプションで指定したファイルを読み込んで実行します。(ただし--noprofileオプションが指定されているかPOSIX 準拠モードの場合を除く)

--profile=ファイル名オプションが指定されていない場合は、~/.yash_profile がデフォルトのファイルとして使われます。

2.シェルが対話モードの場合は、--rcfile=ファイル名オプションで指定したファイルを読み込んで実行します。(ただし--norcfileオプションが指定されている場合を除く)

--rcfileオプションが指定されていない場合は、非 POSIX 準拠モードではファイル~/.yashrc がデフォルトのファイルとして使われます。~/.yashrc が読み込めない場合は、ファイル initialization/default をYASH_LOADPATHから探して読み込みます。POSIX 準拠モードでは、ENV 環境変数の値がパラメータ展開され、その結果をファイル名と見なしてファイルを読み込みます。


注記

Yash は /etc/profile や /etc/yashrc や ~/.profile を自動的に読むことはありません。

 

コマンドの文法

シェルはコマンドを一行ずつ読み込んで解釈し、実行します。一行に複数のコマンドがある場合は、それら全てを解釈してから実行します。一つのコマンドが複数行にまたがっている場合は、そのコマンドを解釈し終えるのに必要なだけ後続の行が読み込まれます。コマンドを正しく解釈できない場合は、文法エラーとなり、コマンドは実行されません。

非対話モードで文法エラーが発生した時は、シェルはコマンドの読み込みを中止するため、それ以降のコマンドは一切読み込まれません。 

トークンの解析と予約語

コマンドは、いくつかのトークンによって構成されます。トークンとは、シェルの文法における一つ一つの単語のことを言います。トークンは原則として空白 (空白文字またはタブ文字) によって区切られます。ただしコマンド置換などに含まれる空白はトークンの区切りとは見なしません。

以下の記号は、シェルの文法において特別な意味を持っています。これらの記号も多くの場合他の通常のトークンの区切りとなります。

; & | < > ( ) [newline]

以下の記号はトークンの区切りにはなりませんが、文法上特別な意味を持っています。

$ ` \ " ' * ? [ # ~ = %

以下のトークンは特定の場面において予約語と見なされます。予約語は複合コマンドなどを構成する一部となります。

! { } case do done elif else esac fifor function if in then until while

これらのトークンは以下の場面において予約語となります。

*それがコマンドの最初のトークンのとき

*それが他の予約語 (case,for,inを除く) の直後のトークンのとき

*それがコマンドの最初のトークンではないが、複合コマンドの中で予約語として扱われるべきトークンであるとき

トークンが # で始まる場合、その # から行末まではコメントと見なされます。コマンドの解釈においてコメントは完全に無視されます。 

クォート

空白や上記の区切り記号・予約語などを通常の文字と同じように扱うには、適切な引用符でクォートする必要があります。引用符は、それ自体をクォートしない限り通常の文字としては扱われません。シェルでは以下の三種類の引用符が使えます。

*バックスラッシュ (\) は直後の一文字をクォートします。

例外として、バックスラッシュの直後に改行がある場合、それは改行をクォートしているのではなく、行の連結と見なされます。バックスラッシュと改行が削除され、バックスラッシュがあった行とその次の行が元々一つの行であったかのように扱われます。

*二つの一重引用符 (') で囲んだ部分では、全ての文字は通常の文字と同じように扱われます。改行を一重引用符で囲むこともできます。ただし、一重引用符を一重引用符で囲むことはできません。

*二つの二重引用符 (") で囲んだ部分も一重引用符で囲んだ部分と同様にクォートされますが、いくつか例外があります。二重引用符で囲んだ部分では、パラメータ展開・コマンド置換・数式展開が通常通り解釈されます。またバックスラッシュは$,`,",\の直前にある場合および行の連結を行う場合にのみ引用符として扱われ、それ以外のバックスラッシュは通常の文字と同様に扱われます。
 

エイリアス

コマンドを構成する各トークンは、それが予め登録されたエイリアスの名前に一致するかどうか調べられます。一致するものがあれば、そのトークンはそのエイリアスの内容に置き換えられて、その後コマンドの解析が続けられます。これをエイリアス置換といいます。

エイリアスの名前に引用符を含めることはできないので、引用符を含むトークンはエイリアス置換されません。また、予約語やコマンドを区切る記号もエイリアス置換されません。

エイリアスには通常のエイリアスとグローバルエイリアスの二種類があります。通常のエイリアスは、コマンドの最初のトークンにのみ一致します。グローバルエイリアスはコマンド内の全てのトークンが一致の対象です。グローバルエイリアスは POSIX 規格にはない拡張機能です。

通常のエイリアスで置換された部分の最後の文字が空白の場合、特例としてその直後のトークンにも通常のエイリアスの置換が行われます。

エイリアス置換の結果がさらに別のエイリアスに一致して置換される場合もあります。しかし、同じエイリアスに再び一致することはありません。

エイリアスを登録するには alias 組込みコマンドを、登録を削除するには unalias 組込みコマンドを使用します。 

単純コマンド

最初のトークンが予約語でないコマンドは、単純コマンドです。単純コマンドは単純コマンドの実行のしかたに従って実行されます。

単純コマンドの初めのトークンが 名前= の形式になっている場合は、それは変数代入と見なされます。ただしここでの名前は、一文字以上のアルファベット・数字または下線 (_) で、かつ最初が数字でないものです。変数代入ではない最初のトークンはコマンドの名前と解釈されます。それ以降のトークンは (たとえ変数代入の形式をしていたとしても) コマンドの引数と解釈されます。

名前=(トークン列) の形になっている変数代入は、配列の代入となります。括弧内には任意の個数のトークンを書くことができます。またこれらのトークンは空白・タブだけでなく改行で区切ることもできます。 

パイプライン

パイプラインは、一つ以上のコマンド (単純コマンド、複合コマンド、または関数定義) を記号 | で繋いだものです。

二つ以上のコマンドからなるパイプラインの実行は、パイプラインに含まれる各コマンドをそれぞれ独立したサブシェルで同時に実行することで行われます。この時、各コマンドの標準出力は次のコマンドの標準入力にパイプで受け渡されます。最初のコマンドの標準入力と最後のコマンドの標準出力は元のままです。

Pipe-fail オプションが無効な時は、最後のコマンドの終了ステータスがパイプラインの終了ステータスになります。有効な時は、終了ステータスが 0 でなかった最後のコマンドの終了ステータスがパイプラインの終了ステータスになります。全てのコマンドの終了ステータスが 0 だった時は、パイプラインの終了ステータスも 0 になります。

パイプラインの先頭には、記号 ! を付けることができます。この場合、パイプラインの終了ステータスが逆転します。つまり、最後のコマンドの終了ステータスが 0 のときはパイプラインの終了ステータスは 1 になり、それ以外の場合は 0 になります。

Korn シェルでは構文 !(...) は POSIX で定義されていない独自のパス名展開パターンと見做されます。POSIX 準拠モードでは !( の二つのトークンは一つ以上の空白で区切る必要があります。


注記

最後のコマンドの終了ステータスがパイプラインの終了ステータスになるため、パイプラインの実行が終了するのは少なくとも最後のコマンドの実行が終了した後です。しかしそのとき他のコマンドの実行が終了しているとは限りません。また、最後のコマンドの実行が終了したらすぐにパイプラインの実行が終了するとも限りません。(シェルは、他のコマンドの実行が終わるまで待つ場合があります)


注記

POSIX 規格では、パイプライン内の各コマンドはサブシェルではなく現在のシェルで実行してもよいことになっています。

 

And/or リスト

And/or リストは一つ以上のパイプラインを記号 && または || で繋いだものです。

And/or リストの実行は、and/or リストに含まれる各パイプラインを条件付きで実行することで行われます。最初のパイプラインは常に実行されます。それ以降のパイプラインの実行は、前のパイプラインの終了ステータスによります。

*二つのパイプラインが&&で繋がれている場合、前のパイプラインの終了ステータスが 0 ならば後のパイプラインが実行されます。

*二つのパイプラインが||で繋がれている場合、前のパイプラインの終了ステータスが 0 でなければ後のパイプラインが実行されます。

*それ以外の場合は、and/or リストの実行はそこで終了し、それ以降のパイプラインは実行されません。

最後に実行したパイプラインの終了ステータスが and/or リストの終了ステータスになります。

構文上、and/or リストの直後には原則として記号 ; または & が必要です (コマンドの区切りと非同期コマンド参照)。 

コマンドの区切りと非同期コマンド

シェルが受け取るコマンドの全体は、and/or リストを ; または & で区切ったものです。行末、 ;; または ) の直前にある ; は省略できますが、それ以外の場合は and/or リストの直後には必ず ;& のどちらかが必要です。

And/or リストの直後に ; がある場合は、その and/or リストは同期的に実行されます。すなわち、その and/or リストの実行が終わった後に次の and/or リストが実行されます。And/or リストの直後に & がある場合は、その and/or リストは非同期的に実行されます。すなわち、その and/or リストの実行を開始した後、終了を待たずに、すぐさま次の and/or リストの実行に移ります。非同期な and/or リストは常にサブシェルで実行されます。また終了ステータスは常に 0 です。

ジョブ制御を行っていないシェルにおける非同期な and/or リストでは、標準入力が自動的に /dev/null にリダイレクトされるとともに、SIGINT と SIGQUIT を受信したときの動作が lq無視rq に設定されこれらのシグナルを受けてもプログラムが終了しないようにします。

ジョブ制御を行っているかどうかにかかわらず、非同期コマンドを実行するとシェルはそのコマンドのプロセス ID を記憶します。特殊パラメータ ! を参照すると非同期コマンドのプロセス ID を知ることができます。非同期コマンドの状態や終了ステータスは jobs や wait 組込みコマンドで知ることができます。 

複合コマンド

複合コマンドは、より複雑なプログラムの制御を行う手段を提供します。


グルーピング

グルーピングを使うと、複数のコマンドを一つのコマンドとして扱うことができます。

通常のグルーピングの構文

{ コマンド...; }

サブシェルのグルーピングの構文

(コマンド...)

{} は予約語なので、他のコマンドのトークンとくっつけて書いてはいけません。一方 () は特殊な区切り記号と見なされるので、他のトークンとくっつけて書くことができます。

通常のグルーピング構文 ({} で囲む) では、コマンドは (他のコマンドと同様に) 現在のシェルで実行されます。サブシェルのグルーピング構文 (() で囲む) では、括弧内のコマンドは新たな:サブシェルで実行されます。

POSIX 準拠モードでは括弧内に少なくとも一つのコマンドが必要ですが、非 POSIX 準拠モードではコマンドは一つもなくても構いません。

グルーピングの終了ステータスは、グルーピングの中で実行された最後のコマンドの終了ステータスです。グルーピング内にコマンドが一つもない場合、グルーピングの終了ステータスはグルーピングの直前に実行されたコマンドの終了ステータスになります。


If 文

If 文は条件分岐を行います。分岐の複雑さに応じていくつか構文のバリエーションがあります。

If 文の基本構文

if 条件コマンド...; then 内容コマンド...; fi

Else がある場合

if 条件コマンド...; then 内容コマンド...; else 内容コマンド...; fi

Elif がある場合

if 条件コマンド...; then 内容コマンド...; elif 条件コマンド...; then 内容コマンド...; fi

Elif と else がある場合

if 条件コマンド...; then 内容コマンド...; elif 条件コマンド...; then 内容コマンド...; else 内容コマンド...; fi

If 文の実行では、どの構文の場合でも、if の直後にある条件コマンドがまず実行されます。条件コマンドの終了ステータスが 0 ならば、条件が真であると見なされて then の直後にある内容コマンドが実行され、if 文の実行はそれで終了します。終了ステータスが 0 でなければ、条件が偽であると見なされます。ここで elseelif もなければ、if 文の実行はこれで終わりです。else がある場合は、else の直後の内容コマンドが実行されます。elif がある場合は、elif の直後の条件コマンドが実行され、その終了ステータスが 0 であるかどうか判定されます。その後は先程と同様に条件分岐を行います。

elif ...; then ...; は一つの if 文内に複数あっても構いません。

If 文全体の終了ステータスは、実行された内容コマンドの終了ステータスです。内容コマンドが実行されなかった場合 (どの条件も偽で、else がない場合) は 0 です。


While および until ループ

While ループと until ループは単純なループ構文です。

While ループの構文

while 条件コマンド...; do 内容コマンド...; done

Until ループの構文

until 条件コマンド...; do 内容コマンド...; done

非 POSIX 準拠モードでは 条件コマンド...; および 内容コマンド...; は省略可能です。

While ループの実行ではまず条件コマンドが実行されます。そのコマンドの終了ステータスが 0 ならば、内容コマンドが実行されたのち、再び条件コマンドの実行に戻ります。この繰り返しは条件コマンドの終了ステータスが 0 でなくなるまで続きます。


注記

条件コマンドの終了ステータスが最初から 0 でないときは、内容コマンドは一度も実行されません。

Until ループは、ループを続行する条件が逆になっている以外は while ループと同じです。すなわち、条件コマンドの終了ステータスが 0 でなければ内容コマンドが実行されます。

While/until ループ全体の終了ステータスは、最後に実行した内容コマンドの終了ステータスです。(内容コマンドが存在しないか、一度も実行されなかったときは 0)


For ループ

For ループは指定されたそれぞれの単語について同じコマンドを実行します。

For ループの構文

for 変数名 in 単語...; do コマンド...; done

for 変数名 do コマンド...; done

in の直後の単語は一つもなくても構いませんが、do の直前の ; (または改行) は必要です。これらの単語トークンは予約語としては認識されませんが、& などの記号を含めるには適切なクォートが必要です。非 POSIX 準拠モードでは コマンド...; がなくても構いません。

POSIX 準拠モードでは、変数名はポータブルな (すなわち ASCII 文字のみからなる) 名前でなければなりません。

For ループの実行ではまず単語が単純コマンド実行時の単語の展開と同様に展開されます (in ...; がない構文を使用している場合は、in "$@"; が省略されているものと見なされます)。続いて、展開で生成されたそれぞれの単語について順番に一度ずつ以下の処理を行います。

1.単語を変数名で指定した変数に代入する

2.コマンドを実行する

単語はローカル変数として代入されます (POSIX 準拠モードのときを除く)。展開の結果単語が一つも生成されなかった場合は、コマンドは一切実行されません。

For ループ全体の終了ステータスは、最後に実行したコマンドの終了ステータスです。コマンドがあるのに一度も実行されなかったときは 0 です。コマンドがない場合、for ループの終了ステータスは for ループの一つ前に実行されたコマンドの終了ステータスになります。

変数が読み取り専用の場合、for ループの実行は 0 でない終了ステータスで中断されます。


Case 文

Case 文は単語に対してパターンマッチングを行い、その結果に対応するコマンドを実行します。

Case 文の構文

case 単語 in caseitem... esac

Caseitem の構文

(パターン) コマンド...;;

casein の間の単語はちょうど一トークンでなければなりません。この単語トークンは予約語としては認識されませんが、& などの記号を含めるには適切なクォートが必要です。inesac の間には任意の個数の caseitem を置きます (0 個でもよい)。Caseitem の最初の (esac の直前の ;; は省略できます。またコマンド; で終わる場合はその ; も省略できます。Caseitem の );; との間にコマンドが一つもなくても構いません。

Caseitem のパターンにはトークンを指定します。各トークンを | で区切ることで複数のトークンをパターンとして指定することもできます。

Case 文の実行では、まず単語が四種展開されます。その後、各 caseitem に対して順に以下の動作を行います。

1.パターントークンを単語と同様に展開し、展開したパターンが展開した単語にマッチするかどうか調べます (パターンマッチング記法参照)。パターンとして指定されたトークンが複数ある場合はそれら各トークンに対してマッチするかどうか調べます (どれかのパターントークンがマッチしたらそれ以降のパターントークンは展開されません。Yash はトークンが書かれている順番にマッチするかどうかを調べますが、他のシェルもこの順序で調べるとは限りません)。

2.マッチした場合は、直後のコマンドを実行し、それでこの case 文の実行は終了です。マッチしなかった場合は、次の caseitem の処理に移ります。

Case 文全体の終了ステータスは、実行したコマンドの終了ステータスです。コマンドが実行されなかった場合 (どのパターンもマッチしなかったか、caseitem が一つもないか、マッチしたパターンの後にコマンドがない場合) は、終了ステータスは 0 です。

POSIX 準拠モードでは、(| で区切られた最初の) パターントークンを esac にすることはできません。

 

関数定義

関数定義コマンドは、関数を定義します。

関数定義コマンドの構文

関数名 ( ) 複合コマンド

function 関数名 複合コマンド

function 関数名 ( ) 複合コマンド

予約語 function を用いない一つ目の形式では、関数名には引用符などの特殊な記号を含めることはできません。予約語 function を用いる二つ目または三つ目の形式では、関数名は実行時に四種展開されます。(POSIX 準拠モードでは、予約語 function を用いる形式の関数定義は使えません。また関数名はポータブルな (すなわち ASCII 文字のみからなる) 名前でなければなりません。)

関数定義コマンドを実行すると、指定した関数名の関数が複合コマンドを内容として定義されます。

関数定義コマンドに対して直接リダイレクトを行うことはできません。関数定義コマンドの最後にあるリダイレクトは、関数の内容である複合コマンドに対するリダイレクトと見なされます。例えば func() { cat; } >/dev/null と書いた場合、リダイレクトされるのは func() { cat; } ではなく { cat; } です。

関数定義コマンドの終了ステータスは、関数が正しく定義された場合は 0、そうでなければ非 0 です。 

パラメータと変数

パラメータとは、パラメータ展開で値に置き換えられるデータを言います。パラメータには位置パラメータ・特殊パラメータ・変数の三種類があります。 

位置パラメータ

位置パラメータは 1 以上の自然数によって識別されるパラメータです。例えば位置パラメータが三つある場合、それらは順に 1, 2, 3 という名称で識別されます。位置パラメータの個数は特殊パラメータ # で取得できます。また全ての位置パラメータを表す特殊パラメータとして *@ があります。

位置パラメータは、シェルの起動時に、シェルのコマンドライン引数を元に初期化されます (起動時のコマンドライン引数参照)。引数のうち、位置パラメータの値として与えられたオペランドが順に一つずつ位置パラメータとなります。

シェルのコマンド実行中に関数が呼び出されるとき、位置パラメータはその関数の呼び出しに対する引数に変更されます。すなわち、関数の実行中は位置パラメータによって関数の引数を参照できます。関数呼び出しの直前の位置パラメータの値は保存されており、関数の実行が終了する際に元の値に戻ります。

位置パラメータは、set や shift などの組込みコマンドによって変更できます。

0 は位置パラメータとは見なされません (特殊パラメータの一つです)。 

特殊パラメータ

特殊パラメータは一文字の記号によって識別されるパラメータです。特殊パラメータにはユーザが明示的に値を代入することはできません。

Yash では以下の特殊パラメータが利用可能です。

0

このパラメータの値は、シェルの起動時に与えられたシェルの実行ファイルの名称またはスクリプトファイルの名称です。(起動時のコマンドライン引数参照)

#

このパラメータの値は、現在の位置パラメータの個数を表す 0 以上の整数です。

$

このパラメータの値は、シェル自身のプロセス ID を表す正の整数です。この値はサブシェルにおいても変わりません。

-

このパラメータの値は、現在シェルで有功になっているオプションの文字をつなげたものです。この値には、シェルの起動時にコマンドライン引数で指定できる一文字のオプションのうち現在有効になっているものが全て含まれます。set 組込みコマンドでオプションを変更した場合は、その変更がこのパラメータの値にも反映されます。

?

このパラメータの値は、最後に終了したパイプラインの終了ステータスを表す 0 以上の整数です。

!

このパラメータの値は、最後に実行した非同期コマンドのプロセス ID です。

*

このパラメータの値は、現在の位置パラメータの値です。位置パラメータが一つもない場合、このパラメータの値は空文字列です。位置パラメータが複数ある場合、このパラメータの値は全ての位置パラメータの値を連結したものです。各位置パラメータの値の間は以下に従って区切られます。

*変数IFSが存在し、その値が空でない場合、各位置パラメータは変数IFSの値の最初の文字で区切られます。

*変数IFSが存在し、その値が空の場合、各位置パラメータは間に何も置かずに連結されます。

*変数IFSが存在しない場合、各位置パラメータは空白文字で区切られます。

このパラメータの展開結果に対して単語分割が行われる場合、値はまず元の位置パラメータに一致するように分割されさらに変数IFSの値に従って分割されます。この最初の分割はIFSが空文字列でも行います。

@

このパラメータは、パラメータ*と同様に現在の全ての位置パラメータを表します。ただし、このパラメータが二重引用符によるクォートの中で展開される場合の扱いがパラメータ*と異なります。この場合、結果は各位置パラメータに正確に一致するように単語分割されます。また位置パラメータが一つもない場合、このパラメータは展開後の単語には残りません。(よって、引用符の中であるにもかかわらず、展開結果は一つの単語になるとは限りません。)

例えば位置パラメータが一つもないとき、コマンドラインecho 1 "$@" 2echo12という三つの単語に展開されます。位置パラメータが12 23の三つのとき、コマンドラインecho "$@"echo12 23という四つの単語に展開され、コマンドラインecho "a$@b"echoa12 23bという四つの単語に展開されます。

 

変数

変数とはユーザが自由に代入可能なパラメータです。各変数は名前で区別され、それぞれが文字列の値を持ちます。

変数の名前は、英数字と下線 (_) から構成されます。ただし変数名の頭文字を数字にすることはできません。環境によってはこれ以外の文字も変数名に使用できます。

シェルが扱う変数のうち、エクスポートの対象となっているものは環境変数といいます。これらの変数はシェルが外部コマンドを起動する際に外部コマンドに渡されます。シェルが起動されたときにシェルを起動したプログラムから渡された変数は自動的に環境変数になります。

変数は、単純コマンドによって代入できます。また typeset 組込みコマンドなどでも変数に代入することができます。変数を削除するには unset 組込みコマンドを使います。


シェルが使用する変数

以下の名前の変数は、yash の実行において特別な意味を持っています。

CDPATH

この変数はcd 組込みコマンドで移動先ディレクトリを検索するために使われます。

COLUMNS

この変数は端末ウィンドウの横幅 (文字数) を指定します。この変数が設定されている場合、デフォルトの横幅ではなくこの変数の値で指定された横幅が行編集で使われます。

COMMAND_NOT_FOUND_HANDLER

シェルが実行しようとしたコマンドが見つからなかったとき、この変数の値がコマンドとして実行されます。不明なコマンドを実行したときに何か別のコマンドを実行させたい時に便利です。単純コマンドの実行を参照。

この機能はPOSIX 準拠モードでは働きません。

DIRSTACK

この配列変数はディレクトリスタックの実装に使われています。pushd 組込みコマンドでディレクトリを移動したとき、前のディレクトリを覚えておくためにそのパス名がこの配列に入れられます。この配列の内容を変更することは、ディレクトリスタックの内容を直接変更することになります。

ECHO_STYLE

この変数はecho 組込みコマンドの挙動を指定します。

ENV

POSIX 準拠モードで対話モードのシェルが起動されたとき、この変数の値で示されるパスのファイルが初期化スクリプトとして読み込まれます (シェルの初期化処理参照)。

FCEDIT

Fc 組込みコマンドでコマンドを編集する際、この変数の値で示されたエディタがコマンドの編集に使われます。

HANDLED

この変数はCOMMAND_NOT_FOUND_HANDLER変数の値が実行された後に、コマンドが見つからなかったことをエラーとするかどうかを指示します。単純コマンドの実行を参照。

HISTFILE

コマンド履歴を保存するファイルのパスを指定します。

HISTRMDUP

コマンド履歴の重複をチェックする個数を指定します。履歴にコマンドを追加する際、既に履歴にあるコマンドのうちここで指定した個数のコマンドが新しく追加されるコマンドと同じかどうかをチェックします。同じコマンドが既に履歴にあれば、それは履歴から削除されます。

例えばこの変数の値が1のときは、履歴に追加されるコマンドが一つ前のコマンドと同じならばそれは削除されます。それより古い履歴のコマンドは、(履歴に追加されるコマンドと同じでも) 削除されません。もしこの変数の値がHISTSIZE変数の値と同じなら、履歴の中で重複するコマンドはすべて削除されます。あるいはもしこの変数の値が0なら、重複する履歴は一切削除されません。

HISTSIZE

コマンド履歴に保存される履歴項目の個数を指定します。

HOME

ユーザのホームディレクトリのパスを指定します。チルダ展開やcd 組込みコマンドの動作に影響します。

IFS

この変数は単語分割の区切りを指定します。シェルの起動時にこの変数の値は空白文字・タブ・改行の三文字に初期化されます。

LANG, LC_ALL, LC_COLLATE, LC_CTYPE, LC_MESSAGES, LC_MONETARY, LC_NUMERIC, LC_TIME

これらの変数はシェルが動作するロケールを指定します。シェルが読み書きするファイルのエンコーディングやエラーメッセージの内容などはこの変数で指定されたロケールに従います。

LC_CTYPE変数の値はシェルの起動時にのみ反映されます。シェルの実行中にこの変数を変更してもシェルのロケールは変わりません (シェルが非POSIX 準拠モードで対話モードの場合を除く)。

LINENO

この変数の値は、現在シェルが読み込んで実行しているファイルにおける、現在実行中のコマンドのある行番号を示します。(対話モードでは、コマンドを入力して実行するたびに行番号は 1 に戻ります)

一度この変数に代入したり変数を削除したりすると、この変数を用いて行番号を取得することはできなくなります。

LINES

この変数は端末ウィンドウの行数を指定します。この変数が設定されている場合、デフォルトの行数ではなくこの変数の値で指定された行数が行編集で使われます。

MAIL

この変数はメールチェックの対象となるファイルのパスを指定します。

MAILCHECK

この変数はメールチェックを行う間隔を秒単位で指定します。この変数の値はシェルの起動時に600に初期化されます。

MAILPATH

この変数はメールチェックの対象となるファイルのパスを指定します。

NLSPATH

POSIX によるとこの変数の値はロケール依存のメッセージデータファイルのパスを指示することになっていますが、yash では使用していません。

OLDPWD

Cd 組込みコマンドなどで作業ディレクトリを変更したときに、変更前の作業ディレクトリパスがこの変数に設定されます。この変数はデフォルトでエクスポート対象になります。

OPTARG

Getopts 組込みコマンドで引数付きのオプションを読み込んだとき、その引数の値がこの変数に設定されます。

OPTIND

この変数の値は、getopts 組込みコマンドで次に読み込むオプションのインデックスを表します。シェルの起動時にこの変数は1に初期化されます。

PATH

この変数は、コマンドの検索時にコマンドのありかを示すパスを指定します。

PPID

この変数の値は、シェルの親プロセスのプロセス ID を表す正の整数です。この変数はシェルの起動時に初期化されます。この変数の値はサブシェルにおいても変わりません。

PROMPT_COMMAND

POSIX 準拠モードでない対話モードのシェルにおいて、シェルが各コマンドのプロンプトを出す直前に、この変数の値がコマンドとして解釈・実行されます。これは、プロンプトを出す直前に毎回eval -i -- "${PROMPT_COMMAND-}"というコマンドが実行されるのと同じですが、このコマンドの実行結果は次のコマンドでの?特殊パラメータの値には影響しません。

PS1

この変数の値は、対話モードのシェルが出力する標準のコマンドプロンプトを指定します。この値の書式についてはプロンプトの項を参照してください。

この変数はシェルの起動時に\$ に初期化されます。(POSIX 準拠モードなら実効ユーザ ID が 0 かどうかによって$ # のどちらか)

PS1R

この変数の値は、対話モードのシェルがコマンドを読み込む際に、入力されるコマンドの右側に表示されるプロンプトを指定します。この値の書式についてはプロンプトの項を参照してください。

PS1S

この変数の値は、対話モードのシェルがコマンドを読み込む際に、入力されるコマンドを表示するフォントの書式を指定します。この値の書式についてはプロンプトの項を参照してください。

PS2

この変数の値は、対話モードのシェルが出力する補助的なコマンドプロンプトを指定します。この値の書式についてはプロンプトの項を参照してください。 この変数はシェルの起動時に> に初期化されます。

PS2R

この変数はPS1R変数と同様ですが、プロンプトとしてPS1変数ではなくPS2変数の値が使用されるときに使用されます。

PS2S

この変数はPS1S変数と同様ですが、プロンプトとしてPS1変数ではなくPS2変数の値が使用されるときに使用されます。

PS4

Xtrace オプションが有効なとき、この変数の値が各トレース出力の前に出力されます。ただし出力の前にこの変数の値に対してパラメータ展開、コマンド置換、数式展開を行います。またPOSIX 準拠モードでなければ、PS1変数と同様に、バックスラッシュで始まる特殊な記法が利用できます。

この変数はシェルの起動時に+ に初期化されます。

PS4S

この変数はPS1S変数と同様ですが、プロンプトとしてPS1変数が使用されるときではなく、トレース出力の際にPS4変数の値が使用されるときに使用されます。この変数を使うとトレース出力のフォントの書式を変更することができます。

PWD

この変数の値は現在の作業ディレクトリの絶対パスを表します。この変数はシェルの起動時に正しいパスに初期化され、cd 組込みコマンドなどで作業ディレクトリを変更する度に再設定されます。この変数はデフォルトでエクスポート対象になります。

RANDOM

この変数は乱数を取得するために使用できます。この変数の値は 0 以上 32768 未満の一様分布乱数になっています。

この変数に非負整数を代入すると乱数を生成するを再設定できます。

一度この変数を削除すると、この変数を用いて乱数を取得することはできなくなります。またシェルがPOSIX 準拠モードで起動された場合、この変数で乱数を取得することはできません。

TERM

この変数は対話モードのシェルが動作している端末の種類を指定します。ここで指定された端末の種類に従って行編集機能は端末を制御します。

YASH_AFTER_CD

この変数の値は、cd 組込みコマンドやpushd 組込みコマンドで作業ディレクトリが変更された後にコマンドとして解釈・実行されます。これは、作業ディレクトリが変わった後に毎回eval -i -- "${YASH_AFTER_CD-}"というコマンドが実行されるのと同じです。

YASH_LOADPATH

ドット組込みコマンドで読み込むスクリプトファイルのあるディレクトリを指定します。PATH変数と同様に、コロンで区切って複数のディレクトリを指定できます。この変数はシェルの起動時に、yash に付属している共通スクリプトのあるディレクトリ名に初期化されます。

YASH_LE_TIMEOUT

この変数は行編集機能で曖昧な文字シーケンスが入力されたときに、入力文字を確定させるためにシェルが待つ時間をミリ秒単位で指定します。行編集を行う際にこの変数が存在しなければ、デフォルトとして 100 ミリ秒が指定されます。

YASH_VERSION

この変数はシェルの起動時にシェルのバージョン番号に初期化されます。


配列

配列とは、一つの変数に複数の値 (文字列) を持たせたものです。一つの配列の複数の値は位置パラメータと同様に 1 以上の自然数で識別されます。

配列は、単純コマンドによって代入できます。また array 組込みコマンドなどでも配列に代入することができます。配列を削除するには変数と同様に unset 組込みコマンドを使います。

配列を配列のままエクスポートすることはできません。配列をエクスポートしようとすると、配列の各値をコロンで区切って繋いだ一つの文字列の値を持つ変数としてエクスポートされます。

POSIX 準拠モードでは配列は使えません。

 

単語の展開

コマンドを構成する各単語は、そのコマンドが実行されるときに展開されます。展開とは単語に含まれるパラメータやパターンを処理して具体的な文字列値に置き換えることです。展開には以下の七種類があります。

1.チルダ展開

2.パラメータ展開

3.コマンド置換

4.数式展開

5.ブレース展開

6.単語分割

7.パス名展開

これらの展開は上に挙げた順序で行われます。特に最初の四つ (チルダ展開・パラメータ展開・コマンド置換・数式展開) を四種展開といいます。 

チルダ展開

チルダ展開は、~ で始まる単語を特定のパス名に置き換える展開です。単語の先頭にある ~ から最初の / まで (/ がない場合は単語全体) が指定されたパス名に変換されます。ただし、置き換えられる部分が一文字でもクォートされている場合は、チルダ展開は行われません。

展開される内容は、置き換えられる部分の書式によって以下のように決まります。

~

単なる~は、HOME 変数の値に置き換えられます。

~ユーザ名

~の後にユーザ名が書かれている場合は、そのユーザのホームディレクトリのパス名に置き換えられます。

~+

~+は、PWD 変数の値に置き換えられます。

~-

~-は、OLDPWD 変数の値に置き換えられます。

~+n, ~-n

このnは 0 以上の整数でなければなりません。この形式のチルダ展開は、+nまたは -nで指定されるディレクトリスタック内のパスの一つに展開されます。(dirs 組込みコマンド参照)

変数代入の値に対してチルダ展開が行われる際、値がコロンで区切ってある場合は、コロンで区切ってある各部分をそれぞれ単語とみなしてチルダ展開します。例えば HOME 変数の値が /home/foo のとき、

VAR=~/a:~/b:~/c

VAR=/home/foo/a:/home/foo/b:/home/foo/c

と等価です。

チルダ展開に失敗した場合 (指定されたパス名が何らかの原因で得られなかった場合) の動作は POSIX では規定されていませんが、yash では何事もなかったかのように処理を続行します (置き換えられるはずだった部分はそのまま残され、エラーメッセージなどは出ません)。

POSIX 準拠モードでは ~~ユーザ名 の形式の展開のみが有効です。 

パラメータ展開

パラメータ展開は、単語の一部をパラメータの値に置き換える展開です。

よく使われる単純なパラメータ展開の形式は ${パラメータ名} です。これはパラメータ名で指定されたパラメータの値に展開されます。さらに、以下の場合にはパラメータ名を囲む括弧を省略して $パラメータ名 のように書くこともできます。

*パラメータ名が特殊パラメータの場合

*パラメータ名が一桁の位置パラメータの場合

*パラメータ名が変数名で、直後に変数名の一部として誤解される恐れのある文字がない場合。例えば${path}-nameという単語は$path-nameと書くこともできますが、${path}name$pathnameと書くことはできません。

パラメータ名として特殊パラメータでも位置パラメータでも変数名でもないものを指定した場合は、構文エラーになります。(Yash 以外のシェルでは構文エラーではなく展開エラーになるものもあります)

シェルの unset オプションが無効な場合、パラメータ名に存在しない変数を指定すると展開エラーになります。Unset オプションが有効な場合は、存在しない変数は空文字列に展開されます。

より複雑なパラメータ展開の形式では、パラメータの値を加工することができます。パラメータ展開の一般形は以下の通りです。

パラメータ展開

${ 前置詞 パラメータ名 インデックス 加工指定 }

ここでは便宜上パラメータ名インデックスの周りに空白を入れましたが、実際には空白を入れてはいけません。パラメータ名以外の部分はいずれも省略可能です。


前置詞

前置詞としてパラメータ名の直前に記号 # を置くことができます。この場合、このパラメータ展開はいま展開しようとしている値の文字数を表す整数に展開されます。展開しようとしているのが配列変数の場合、各要素がそれぞれ文字数を表す整数に置き換えられます。


パラメータ名

パラメータ名には、特殊パラメータ・位置パラメータ・変数を指定することができます。この場合、パラメータ展開は指定されたパラメータの値に展開されます。指定したパラメータ名が配列変数の場合、配列の各要素が特殊パラメータ @ の場合と同様に単語分割されます (インデックス [*] が指定された場合を除く)。

パラメータ名としてパラメータ展開・コマンド置換・数式展開を指定することもできます。これは特に展開の入れ子と言います。この場合、パラメータ展開は内側の展開の展開結果に展開されます。なお、内側のパラメータ展開の括弧 { } は省略できません。また展開の入れ子は POSIX 準拠モードでは使えません。


インデックス

インデックスは展開する値の一部を抜き出すのに使います。インデックスは以下の書式をしています。

インデックス

[単語1]

[単語1,単語2]

ここでの単語1および単語2は通常のトークンと同様に解釈されますが、,] で強制的に区切られます。また空白やタブはトークンの区切りとはみなしません。

インデックスは、以下のように解釈されます。

1.まず、インデックスに含まれる単語1単語2に対してパラメータ展開・コマンド置換・数式展開を行います。

2.インデックス[単語1]の書式をしていて、単語1の上記展開結果が*@#のいずれかの場合は、インデックスの解釈は終了です。

3.単語1単語2の上記展開結果を数式とみなして、数式展開と同様に計算します。計算の結果得られる整数がインデックスとなります。数式展開の結果が整数でない場合は展開エラーです。単語2がない形式でインデックスを指定している場合は、単語2単語1と同じ整数を指定しているものとみなされます。

パラメータ名が配列変数の場合または特殊パラメータ * または @ の場合、インデックスは配列の要素または位置パラメータの一部を指定しているものとみなされます。パラメータ名が上記以外の場合は、パラメータの値の一部を指定しているものとみなされます。インデックスで選択された配列の要素またはパラメータの値の一部のみが、パラメータ展開の結果として展開結果に残ります。インデックスによる選択について以下の規則が適用されます。