対話モード

対話モードは、利用者が直接シェルを操作することを意図したモードです。シェルの起動時に -i オプションを指定した場合 (その他対話モードが有効になる条件が満たされている場合)、シェルは対話モードになります。シェルが起動した後は、そのシェルの対話モードのオン・オフを切り替えることはできません。

対話モードが有効な時……

プロンプト

対話モードでは、シェルはコマンドの入力を読み取る直前にプロンプトを標準エラーに出力します。プロンプトの内容は PS1 変数で指定します。ただし、複数行にわたるコマンドを読み取る際、二行目以降の読み取りには PS1 ではなく PS2 変数の値がプロンプトとして表示されます。

プロンプトの表示の際には、まず PS1 (または PS2) 変数の値がパラメータ展開コマンド置換数式展開で展開されます (ただし POSIX によればパラメータ展開だけが行われることになっています)。この展開後の値は以下の通り解釈され、その結果がプロンプトとして標準エラーに出力されます。

POSIX 準拠モードでは、値に含まれる ! はこれから入力しようとしているコマンドの履歴番号に変換されます。感嘆符そのものをプロンプトに表示させるには !! と二つ続けて書きます。これ以外の文字はプロンプトにそのまま表示されます。

POSIX 準拠モードでないときは、バックスラッシュで始まる以下の記法が解釈されます。これらの記法以外の文字はそのままプロンプトに表示されます。

\a
ベル文字 (ASCII コード番号 7)
\e
エスケープ文字 (ASCII コード番号 27)
\j
現在シェルが抱えているジョブの数
\n
改行文字 (ASCII コード番号 10)
\r
復帰文字 (ASCII コード番号 13)
\!
これから入力しようとしているコマンドの履歴番号
\$
シェルの実行ユーザ ID が 0 のとき #
シェルの実行ユーザ ID が 0 以外のとき $
\\
バックスラッシュ \
\[
\]
この二つの記法は、実際には端末に表示されないプロンプトの一部分を指示するのに使います。\[\] で囲んだ部分は、行編集がプロンプトの文字数を計算する際に、文字数に数えられません。端末に表示されないエスケープシーケンスなどをプロンプトに含める際は、その部分を \[\] でで囲んでください。この指定を怠ると、行編集の表示が乱れることがあります。
\fフォント指定.
行編集を使用している場合、この記法は端末のフォントの表示を変更するための特殊な文字の羅列に変換されます (端末が対応している場合のみ)。行編集を使用していない場合や端末が対応していない場合は、この記法は単に無視されます。フォント指定の部分にはフォントの種類を指定するための以下の文字を指定します。
k
文字の色を黒にする
r
文字の色を赤にする
g
文字の色を緑にする
y
文字の色を黄にする
b
文字の色を青にする
m
文字の色をマゼンタにする
c
文字の色をシアンにする
w
文字の色を白にする
K
背景の色を黒にする
R
背景の色を赤にする
G
背景の色を緑にする
Y
背景の色を黄にする
B
背景の色を青にする
M
背景の色をマゼンタにする
C
背景の色をシアンにする
W
背景の色を白にする
t
文字または背景の色を明るくする (上記の文字・背景の色を変更する文字の直後でのみ有効)
d
文字と背景の色を標準状態に戻す
s
文字を目立たせる
u
文字に下線を引く
v
文字の色を反転させる
b
文字を点滅させる
i
文字の色を暗くする
o
文字を太く目立たせる
x
文字を見えなくする
D
色と装飾を標準状態に戻す
文字と背景の色は最終的に端末によって決まるため、実際にはここで指定した色と異なる色で表示されることがあります。

入力するコマンドの右側に表示されるプロンプトを指定することもできます (右プロンプト)。PS1/PS2 変数に対応する右プロンプトは PS1R/PS2R 変数で指定します。

また、プロンプトのフォントだけでなく、入力するコマンドのフォントを変えることもできます。PS1S (または PS2S) 変数に上述のフォントを指定するシーケンスを指定することで、コマンド入力時のコマンドのフォントが変わります。

POSIX 準拠モードでないときは、プロンプトを出す前に PROMPT_COMMAND 変数の値がコマンドとして実行されます。

コマンド履歴

コマンド履歴は実行したコマンドを記録し後で再び実行することのできる機能です。対話モードでシェルが読み込んだコマンドは自動的にコマンド履歴に記録されます。履歴に記録したコマンドは行編集で呼び出して再実行することができます。また fchistory 組込みコマンドで履歴のコマンドを再実行したり編集したりすることもできます。

コマンドは行単位で履歴に記録されます。空白以外の文字を一切含まない行は履歴には記録されません。また histspace オプションが有効なときは空白で始まる行は履歴に記録されません。

コマンド履歴の内容は HISTFILE 変数で指定されるファイルに保存されます。対話モードのシェルの起動後に履歴関連の機能が初めて使用されるとき、HISTFILE 変数の値をファイル名とみなしてファイルを開きます。既にファイルに履歴データが保存されている場合は、それが読み込まれます。ファイルが存在しないか内容が履歴データではない場合は、新しい履歴ファイルに初期化されます。HISTFILE 変数が存在しない場合やファイルを開くことができない場合は履歴はファイルに保存されませんが、履歴機能自体は使用できます。

シェルが記録するコマンドの数は HISTSIZE 変数で指定します。履歴の件数がこの変数の値を超えると順次古いデータから削除されます。この変数が存在しない場合または値が自然数でない場合は、履歴は 500 件まで記録されます。

HISTFILE および HISTSIZE 変数は履歴機能が初めて使用されるときにのみ参照され、それ以降は変数を再設定しても履歴機能の動作に影響しません。履歴機能が利用されるときというのは、具体的には以下のタイミングです。

このため HISTFILEHISTSIZE 変数は原則としてシェルの起動時に読み込まれる初期化スクリプトの中で設定する必要があります。

複数のシェルプロセスが同じ履歴ファイルを使用している場合、これらのシェルは一つの履歴データを共有します。このとき例えばあるシェルプロセスで実行したコマンドを別のシェルプロセスで実行することができます。同じ履歴を使用しているシェルの間で HISTSIZE が異なっていると履歴が正しく共有されないので、HISTSIZE の値は統一するようにしてください。

Yash は独自の形式の履歴ファイルを使用しているため、履歴ファイルを他の種類のシェルと共用することはできません。

履歴に同じコマンドを記録する無駄を解消するため、HISTRMDUP 変数を使用することができます。新しくコマンドを履歴に記録しようとする際、すでに同じコマンドが最近の $HISTRMDUP 件の履歴データの中に記録されていれば、その既に記録されているコマンドは履歴から削除されます。

メールチェック

対話モードのシェルには、電子メールが届いたらそれを知らせる機能があります。これは所定のファイルの更新日時を調べて、更新日時が変わっていたらメッセージを表示するというものです。受信したメールのデータが保存されるファイルをチェック対象として指定しておくことで、メールを受信したときにメッセージが表示されるようになります。

ファイル更新のチェックはシェルがプロンプトを出す直前に行います。チェックを行う間隔を MAILCHECK 変数で指定することができます。この変数で指定した秒数が経過するごとに、シェルはプロンプトを出す直前にチェックを行います。この変数の値が 0 になっている場合は、プロンプトを出す直前に毎回チェックを行います。また変数の値が 0 以上の整数でない場合は、チェックは一切行いません。

更新日時をチェックする対象のファイルは MAIL 変数で指定します。この変数にチェックしたいファイルのパス名を指定しておくと、シェルはそのファイルの更新日時をチェックします。ファイルの更新日時が前回チェックしたときと変わっていたら、新着メールを知らせるメッセージを標準エラーに出力します。

複数のファイルをチェックの対象にしたい場合やメッセージを自分で指定したい場合は、MAIL 変数の代わりに MAILPATH 変数を使うことができます。MAILPATH 変数が設定されている場合は、MAIL 変数の設定は無視されます。MAILPATH 変数の値には、複数のファイルのパス名をコロン (:) で区切って指定することができます。シェルは毎回のチェックでそれぞれのファイルの更新日時を調べ、ファイルが更新されていたらメッセージを表示します。メッセージを自分で指定するには、パス名の直後にパーセント (%) を置き、続けて表示させたいメッセージを置きます。それぞれのファイルごとに異なるメッセージを指定することができます。(パーセントをパス名とメッセージとの区切りではなくパス名の一部としたい場合はパーセントをバックスラッシュでクォートしてください) パーセントの後に指定されたメッセージは、表示の前にパラメータ展開されます。例えば MAILPATH 変数の値が /foo/mail%New mail!:/bar/mailbox%You've got mail:/baz/mail\%data だとすると、ファイル /foo/mail が更新されたときは New mail! が、/bar/mailbox が更新されたときは You've got mail が、/baz/mail%data が更新されたときはデフォルトのメッセージが表示されます。