SH(1)

名称
sh - コマンドインタプリタ (シェル)

書式
sh [-/+abCEefIimnpsTuVvx] [-/+o longname] [-c string] [arg ...]

解説
sh ユーティリティ はシステムの標準コマンドインタプリタです。 現在 sh は p1003.2 のシェル規約に対応する途上にあります。 本バージョンのシェルは、見方によっては Korn shell と同様に 見える機能を多数持っていますが、 pdksh(1) のような Korn shell クローンではありません。 このシェルには、POSIX で規定された仕様といくつかの Berkeley 拡張のみが 取り入れられています。 本マニュアルは、shell のチュートリアルでは ありませんし、仕様を完全に記述するものでもありません。

  概要
シェルは、ファイルまたは端末から 1 行ずつ読み込み、それを解釈し、 コマンドを実行します。シェルはユーザがシステムにログインしたときに起動 されるプログラムです (ただし、ユーザは chsh(1) コマンドによって他のシェルを選択することもできます)。 シェルは、制御構文を持つ言語であり、 データ記憶をはじめとして多様な機能を提供するマクロ機能、 ヒストリ、行編集機能も内蔵しています。 このシェルは対話的に使うときに便利な機能を多くとり入れており、 対話的に用いるときも非対話的に (シェルスクリプトとして) 用いるときも、 共通のインタプリタ言語を用いることができる利点があります。 すなわち、コマンド名をシェルに直接タイプする ことも、コマンド名をファイルに書いておいてそのファイルをシェルに 直接実行させることもできます。

  起動
引数が与えられず、かつシェルの標準入力が端末の場合 (または -i フラグが指定 された場合)、シェルは対話的に動作します。対話的シェルは、通常、コマンド 入力時にプロンプトを表示し、文法的なエラーとコマンドエラーを 異なった方法で処理します (後述します)。 起動時に、シェルは 0 番目の引数を検査します。もしそれが マイナス記号 (-) で始まっているなら、シェルはログインシェルとして 動作します。ユーザがシステムにログインした場合は自動的にこの状況に なります。ログインシェルは、まず (以下の各ファイルが存在する場合)、 /etc/profile と次に .profile ファイルからコマンドを読み込みます。 シェル起動時に、もしくはログインシェルで .profile を実行中に環境変数 ENV が設定されているなら、シェルは、その次に環境変数 ENV で示されたファイルからコマンドを読み込みます。 つまり、ユーザはログイン時にのみ実行したいコマンドを .profile に書き、シェルが起動されるたびに実行したいコマンドを環境変数 ENV で示すファイルに書くことになります。 環境変数 ENV を設定するには、ホームディレクトリ下のファイル .profile に以下のように記述します。 ここで .shinit のかわりに好きな名前を指定することができます。

    ENV=$HOME/.shinit; export ENV

コマンドライン引数で指定されたオプション以外の最初のものを、シェルは コマンドを読み込むべきファイル (シェルスクリプト) の名前であると解釈し、 それ以後の引数はシェルの位置パラメータ ($1, $2, ...) に設定します。 それ以外の場合、シェルはコマンドを標準入力から読み込みます。

古いバージョンの sh とは異なり、環境変数 ENV で指定したスクリプトが実行されるのは、対話的シェルの呼び出し時のみです。 これにより、いい加減に書かれた ENV スクリプトに起因する、簡単に食いものにされることが多い有名な セキュリティホールがふさがれたことになります。

  引数リスト処理
sh の 1 文字からなるオプションはそれぞれ対応する長い名前を持っています。 ただし -c と -/+o は例外です。 次の解説では、長い名前は単一文字オプションの後で説明します。 あるオプションの長い名前は、 sh(1) の -/+o オプションへの引数として指定可能です。 シェルが起動されると、 オプションの長い名前を set 組み込みコマンド (後述の 組み込みコマンド で説明) の -/+o オプションへの引数として指定可能です。 マイナス記号 (-) でオプションを指定することは、そのオプションを有効にすることを意味し、 プラス記号 (+) でオプションを指定することは、そのオプションを無効にすることを意味します。 “--” または、単なる “-” はオプション処理を終了させ、 コマンドラインの残りの語を引数として解釈することを強制します。 -/+o と -c のオプションは長い名前を持ちません。

-a allexport
    値が代入されたときに変数をエクスポートするよう、変数にフラグを付けます。

-b notify
    バックグラウンドジョブ実行の完了を、コマンドが実行中でも即座に報告しま す (未実装です)。

-C noclobber
    すでに存在するファイルに対して “>” リダイレクトにより上書きしません (未実装です)。

-E emacs
    組み込みの emacs(1) 風のコマンド行編集機能を有効にします (それ以前に -V オプションが指定された場合、それを無効にします)。

-e errexit
    非対話モードで、テスト状態にないコマンドの実行に失敗した場合、 直ちにシェルを終了します。 コマンドは、if, elif, while, until 構文を 制御するのに用いられている場合に、テスト状態であるとみなされます。 また、 “&&” や “||” の左辺値として用いられているコマンドも、テスト状態とみなされます。

-f noglob
    パス名展開を行ないません。

-I ignoreeof
    対話的シェルの場合、入力の EOF を無視します。

-i interactive
    シェルが対話的に動作するように強制します。

-m monitor
    ジョブ制御を可能にします (対話的シェルの場合は自動的に設定されます)。

-n noexec
    非対話的シェルの場合、コマンドを読み込みますが、そのコマンドの実行は しません。シェルスクリプトの文法を検査する場合に便利です。

-p privileged
    特権モードを有効にします。 起動時に実効ユーザ ID あるいは実効グループ ID が、実ユーザ ID や実グルー プ ID と一致していなければ、このモードが有効になります。このモードを無 効化すると、実効ユーザ ID および実効グループ ID は、実ユーザ ID および 実グループ ID に設定されます。 対話的シェルでこのモードが有効になっていると、 /etc/profile の後で ~/.profile に代わり、 /etc/suid_profile を読み込みます。一方、環境変数 ENV の内容は無視されます。

-s stdin
    コマンドを標準入力から読み込みます (引数でファイル名が指定されていない 場合には、このオプションが自動的に設定されます)。 シェルが実行されてから本オプションを ( set などによって) 設定しても効果はありません。

-T asynctraps
    子を待つとき、即座にトラップを実行します。 本オプションが設定されていないと、 p1003.2 で指定されているように、子が終了した後にトラップが実行されます。 この非標準オプションは、 シグナルをブロックする子の周囲に保護シェルを置くために有用です。 周囲のシェルは子を殺したり、 次のように、制御を tty に戻して子だけを残したりできます:

        sh -T -c "trap 'exit 1' 2 ; some-blocking-program"

-u nounset
    値が設定されていない変数を展開しようとした場合、 標準エラー出力にエラーメッセージを出力し、 さらに非対話的シェルならば、ただちにシェルを終了します (未実装です)。

-V vi
    組み込みの vi(1) 風の行編集機能を有効にします (それ以前に -E オプションが指定されていた場合、それは無効になります)。

-v verbose
    入力を読み込むごとに標準エラー出力に書き出します。デバッグのときに便利です。

-x xtrace
    各コマンドを実行する前に、そのコマンドを標準エラー出力に (各コマンドの 前に “+ ” を付加して) 書き出します。デバッグのときに便利です。

-c オプションは、シェルの入力として解釈させる文字列引数を渡すために使用可能です。 このオプションは引数として文字列を一つだけ受け取ることに注意して下さい。 ですから、複数の単語からなる文字列は引用符で囲う必要があります。

-/+o オプションは、オプションの長い名前のみを引数としてとり、 オプションの有効化と無効化を行います。 例えば、次の 2 つの sh 起動方法では組み込みの emacs(1) コマンドラインエディタを有効化します:

    set -E
    set -o emacs

  構文構造
シェルは、ファイルを行単位で読み込み、空白文字 (ブランクおよびタブ) や シェルにとって特別な意味を持つ特定の文字列 ( “演算子” と呼ばれるものです) を区切りとして、複数の単語に分割します。演算子には、制御演算子とリ ダイレクト演算子の 2 種類があります (これらの意味については後述します)。 以下に、それらの一覧を示します。

制御演算子:

    & | && | (| ) | \n

    ;; | ; | | | ||

リダイレクト演算子:

    < | > | << | >> | <>

    <& | >& | <<- | >|

  引用 (クォート)
引用は、特殊な意味を持つ文字や単語 (演算子、空白、キーワードなど) の意味 を打ち消すために用います。引用には、シングルクォート文字のペアを使う方法、 ダブルクォート文字のペアを使う方法、バックスラッシュ文字を使う方法 の 3 種類があります。

シングルクォート文字
    シングルクォートのペアで囲まれた文字は、すべてその文字そのまま (リテラル) として扱われます (ただしシングルクォートは別です。シングルクォート で囲った文字列の中にシングルクォートを含めることはできません)。

ダブルクォート文字
    ダブルクォートのペアで囲まれた文字は、ドル記号文字 ($) 、バッククォート文字 (`) 、バックスラッシュ文字 (\) を除き、すべてリテラルとして扱われます。 ダブルクォート文字による引用の中にあるバックスラッシュ文字は、歴史 的経緯によりすこし変わった扱いを受けます。 次の文字の前にある場合はクォートになりますが、 それ以外ではリテラルのままとなります:

    $ | ` | " | \ | \n

バックスラッシュ
    バックスラッシュは、その後ろの 1 文字を、リテラルとして扱うように指示 します。ただし改行文字 (\n) は別です。改行文字の直前のバックスラッシュは、行 の継続であるとみなされます。

  予約語
予約語はシェルにとって特別な意味を持つ単語で、行の先頭または制御演算子 の直後でのみ予約語として認識されます。以下に予約語の一覧を挙げます。

! | { | } | case | do

done | elif | else | esac | fi

for | if | then | until | while

  エイリアス
エイリアスは、名前とそれと対応する値が対になったもので、 組み込みコマンド alias によって定義されます。 シェルは、予約語が現れる可能性がある場所 (上記を参照) で、 ある単語に対して、それが予約語かどうかの検査を済ませたのち、 それがエイリアスに一致するかどうかを検査します。 もし一致したならば、入力行の中で、その単語をエイリアスの値に置き換えます。 たとえば、 “lf” という名前で “ls -F” という値を持つエイリアスが 存在したとすると、次の入力行

    lf foobar

は、以下のように置換されます。

    ls -F foobar

エイリアスは、初心者に対し、引数付きの関数を生成する面倒を求めることなく、 短いコマンドをつくり出す便利な方法を提供するものです。 しかし、構文的にあいまいなコードを作り出すことにもつながりかねません。 そのような使い方はお勧めできません。

  コマンド
シェルは、読み込んだ単語を、文法に従って解釈します。 本マニュアルでは文法については解説しません。 p1003.2 の BNF 表記を参照してください。要するに、行を1行を読み込み、読み込んだ 行の最初の単語 (制御演算子がある場合は、そのあとの最初の単語) が予約語 でない場合、シェルはその行を単純コマンドとして解釈します。それ以外の場 合、複合コマンドあるいは特殊構造であると解釈します。

  単純コマンド
単純コマンドを解釈する場合、シェルは以下のような動作をします。

1.  単語の前にある “name=value” の形式の単語を取り除き、 単純コマンドの環境に代入します。 リダイレクト演算子とその引数 (後述) を取り除き、 あとで処理できるように保存します。

2.  残った単語を、 単語展開 の節で説明する方法で展開します。 展開後の最初の単語をコマンド名とみなし、コマンドの位置を探索します。 残りの単語はコマンドへの引数とみなされます。 処理の結果、コマンド名が残らなかった場合、手順 1) で 取り出した “name=value” の変数代入を、現在のシェルの環境に反映します。

3.  次節で説明する方法で、リダイレクトを行ないます。

  リダイレクト
リダイレクトは、コマンドがどこから入力するか、どこへ出力するかを 変更するときに用います。 一般には、リダイレクトでは、ファイルのオープン、クローズ、または ファイルへの参照の複製 (duplicate) を行います。 リダイレクトで用いられる全般的な形式は、以下のとおりです。

    [n] redir-op file

ここで、 ‘redir-op’ は前述したリダイレクト演算子のいずれかです。 これらの演算子をどのように利用するかの例をいくつか以下に挙げます。

[n]> file
    標準出力 (またはファイル記述子 n) を file にリダイレクトします

[n]>| file
    上と同様。ただし -C オプションの効果を打ち消します。

[n]>> file
    標準出力 (またはファイル記述子 n) を file に追加します。

[n]< file
    標準入力 (またはファイル記述子 n) を file からリダイレクトします。

[n]<> file
    標準入力 (またはファイル記述子 n) を file から/へ、リダイレクトします。

[n1]<&n2
    ファイル記述子 n2 を標準入力 (またはファイル記述子 n1) に複製します。

[n]<&-
    標準入力 (またはファイル記述子 n) をクローズします。

[n1]>&n2
    標準出力 (またはファイル記述子 n1) をファイル記述子 n2 に複製します。 (訳注: 通常は「ファイル記述子 n2 を標準出力 (またはファイル記述子 n1) に 複製」と表現します。 結果は、標準出力 (または n1 への出力) の n2 へのリダイレクトです。)

[n]>&-
    標準出力 (または n) をクローズします。

以下のリダイレクトは、しばしば “ヒア・ドキュメント (here-document)” と 呼ばれます。

    [n]<< delimiter
    	here-doc-text
    	...
    delimiter

シェルは、delimiter までの行を保存し、コマンドへの標準入力またはファイ ル記述子 n にリダイレクトします。最初の行の delimiter が引用 (クォート) されていた場合、here-doc-text の内容をリテラルとして扱います。 そうでない場合、パラメータ展開、コマンド置換、数値演算 ( 単語展開 の節で 説明します) を適用します。演算子が ( “<<” でなく) “<<-” の場合は、 here-doc-text の各行の行頭のタブを取り除きます。

  コマンド検索と実行
コマンドには、シェル関数、組み込みコマンド、通常プログラムの 3 種類があり、 コマンドを検索する際には、シェルは名前の検索をこの順序で行います。 3 種類のコマンドは異なる方法で実行されます。

シェル関数を実行するとき、$0 を除くすべての位置パラメータ ($1, $2,..) をシェル関数への引数として設定します。$0 は変更されません。シェル関数 の環境として指定された変数 (関数名の直前に “name=value” を置いて指定 されたもの) は、その関数に局所的な変数となり、指定された初期値が設定さ れます。そして、シェルは関数定義で与えられたコマンドを実行します。コマ ンドの実行が完了すると、位置パラメータを元の値に戻します。これは全て現 在のシェルの中で処理されます。

組み込みコマンドは、新たなプロセスを作成せずにシェル内部で実行されます。

コマンドが関数でも組み込みコマンドでもない場合は、通常のプログラムとみなし (次節で説明するとおり) ファイルシステムの中でそのコマンドを検索します。 通常のプログラムを実行する場合、シェルは引数と 環境をプログラムに渡して、そのプログラムを実行します。 プログラムが通常の実行ファイル形式ではない場合 (つまり、 ASCII 表現で "#!" となる "マジックナンバ" でファイルが始まっておらず、 execve(2) が ENOEXEC を返す場合)、 サブシェルの中でそのプログラムを解釈実行します。この場合、あたかも新たに シェルが起動されたかのような効果を得るために、子シェルは自分自身を 再初期化します。ただし、子プロセスは、親シェル中のハッシュされたコマンド 位置情報を憶えており、これは再初期化されません。

本ドキュメントの古いバージョンや古いソースコードでは、ときおり、 マジックナンバのないシェルスクリプトのことを "シェル手続き" と呼んでいて、 まぎらわしい場合がありますので注意して下さい。

  パス検索
コマンドを検索するとき、シェルは、まず、その名前のシェル関数があるかどうかを 調べます。次に、その名前の組み込みコマンドがあるかどうかを調べます。 組み込みコマンドでもない場合、以下のいずれかの処理が行われます:

1.  コマンド名にスラッシュが含まれていれば、検索は行わず、 単にそのコマンドが実行されます。

2.  変数 PATH に含まれる各エントリに対して、順にそのコマンドを検索します。 変数 PATH の値はコロンで区切られたエントリの列でなければなりません。 各エントリは、それぞれディレクトリ名一つに対応します。 カレントディレクトリは、 空のディレクトリ名を指定することで暗黙的に、 あるいは 1 個のピリオドを指定することで明示的に 指示することができます。

  コマンドの終了ステータス
各コマンドは終了ステータスを持ち、それにより他のシェルコマンドの動作に 影響を与えることができます。基本的な考え方として、終了ステータス 0 は 通常の終了または成功を示します。0 以外の終了ステータスは失敗、エラーを 意味します。各コマンドのマニュアルにそれぞれの終了ステータスがどのよう な意味を持つかが記述されているはずです。組み込みコマンドと (実行された) 関数も終了ステータスを返します。

コマンドがシグナルにより終了 (terminate) させられた場合、 終了ステータスは 128 にシグナル番号を加えたものになります。 シグナル番号はヘッダファイル <sys/signal.h> に定義されています。

  複合コマンド (Complex Commands)
複合コマンドは、単純コマンドの組み合わせで作ります。 制御演算子または予約語と組み合わせることで、より大きな複合コマンドを生 成します。一般に、コマンドは以下のうちのいずれかです。

単純コマンド

パイプライン

リストまたは合成リスト (compound-list)

合成コマンド (compound command)

関数定義

特に指定のない場合、コマンドの終了ステータスは最後に実行された 単純コマンドの終了ステータスとなります。

  パイプライン
パイプラインは、複数のコマンドを制御演算子 `|' によってつないだものです。 最後のコマンドを除くすべてのコマンドの標準出力は、次のコマンドの標準入力に 接続されます。 最後のコマンドの標準出力は、通常通り、シェルから受け継がれます。

パイプラインの形式は次のとおりです。

    [!] command1 [| command2 ...]

command1 の標準出力は command2 の標準入力に接続されます。コマンドの標 準入出力がパイプラインによって割り当てられるのは、各コマンドに属する リダイレクト演算子で指定されたリダイレクトを処理する前のことだと考えて 下さい。

パイプラインがバックグラウンド (後述) でなければ、シェルはすべての コマンドが終了するのを待ちます。

パイプラインの直前に予約語 `!' が置かれなかった場合、終了ステータスは パイプラインの最後のコマンドの終了ステータスとなります。 `!' が前置された場合、終了ステータスはパイプラインの最後のコマンドの 終了ステータスの論理否定を取った値となります。 すなわち、最後のコマンドが 0 を返した場合、パイプラインの 終了ステータスは 1 に、最後のコマンドが 0 より大きな値を返した場合、 終了ステータスは 0 になります。

パイプラインによる標準入出力の接続はリダイレクトに先立って行われるため、 パイプラインの接続をリダイレクトによって修正することができます。たとえば、

    $ command1 2>&1 | command2

‘command1’ の標準出力と標準エラー出力の両方を ‘command2’ の標準入力に 接続します。

“”; または改行文字を終端として用いることにより、直前の AND-OR リスト ( 短絡リスト演算子 で後述) を順次実行します。 “&” は、直前の AND-OR リストを非同期に実行します。

注: 他のいくつかのシェルと異なり、 sh ではパイプラインの各プロセスは起動した sh の子プロセスとなります。シェルの組み込みコマンドである ときは別です。その場合は現在のシェルで実行されますが、 環境に対する操作は影響を与えません。

  バックグラウンドコマンド (&)
コマンドが制御演算子がアンパサンド (&) で終了している場合、シェルはそのコマンドを 非同期に実行します。すなわち、シェルはそのコマンドの終了を待たずに、 次のコマンドの実行を開始します。

コマンドをバックグラウンドで実行させるための形式は以下のとおりです。

    command1 & [command2 & ...]

シェルが対話的でない場合、非同期コマンドの標準入力には /dev/null が 接続されます。

  リスト (一般的な話)
リストは 0 個またはそれ以上のコマンドを改行文字、セミコロン文字、アン パーサント文字 (&) で区切った列です。リストは、これら 3 つの記号のいずれかで 終了させることもできます。リスト中のコマンドは並べられた順に実行 されます。もし、コマンドに続けてアンパーサント文字が置かれている場合、 シェルはそのコマンドを起動したあと、すぐに次のコマンドの処理を開始します。 その他の場合、そのコマンドの終了を待ってから次のコマンドの処理を開始します。

  短絡リスト演算子 (Short-Circuit List Operators)
“&&” と “||” は AND-OR リスト演算子です。 “&&” は最初のコマンド を実行し、もし最初のコマンドの終了ステータスが 0 ならば次のコマンドを 実行します。 “||” も同様ですが、最初のコマンドの終了ステータスが 0 でない場合に、次のコマンドを実行します。 “&&” と “||” の優先順位は 同じです。

  制御構造 (if, while, for, case)
if コマンドの文法は以下のとおりです。
    if list
    then list
    [elif list
    then list] ...
    [else list]
    fi

while コマンドの文法は以下のとおりです。
    while list
    do list
    done

最初のリストの終了ステータスが 0 であるかぎり、2 つのリストを繰り返し 実行します。 until コマンドも同様に実行しますが、 単語 while の代わりに単語 until を使うことと、 最初のリストの終了ステータスが 0 になるまで、 2 つのリストを繰り返し実行することが異なります。

for コマンドの文法は以下のとおりです。
    for variable in word ...
    do list
    done

各 word は展開され、変数 variable に word を順に設定しながらリストを 繰り返し実行します。 do と done は “{” と “}” で置き換えることができます。

break と continue コマンドの文法は以下のとおりです。
    break [num]
    continue [num]

break は内側から num 個の for ループまたは while ループを終了します。 continue は内側から num 個のループの次の繰り返しに制御を移します。 これらのコマンドは組み込みコマンドとして実装されています。

case コマンドの文法は以下のとおりです。
    case word in
    pattern) list ;;
    ...
    esac

pattern は、1 つあるいは複数のパターン (後述の シェルパターン を参照のこと) を “|” で接続したものです。

  複数のコマンドのグループ化
コマンドは、以下のいずれかの方法によりグループ化することができます。

    (list)

または、

    { list; }

最初の形式では、コマンドはサブシェル上で実行されます。 この組み込みコマンドは現在のシェルには影響を与えないことに注意してください。 2 つめの形式では新たなシェルを fork しないので、やや効率が良くなります。 このようにして複数コマンドをグループ化することで、 あたかも単一プログラムであるかのように、それらの出力をまとめて リダイレクトすることができます。

    { echo -n "hello"; echo " world"; } > greeting

  関数
関数定義の構文は以下のとおりです。

    name ( ) command

関数定義は実行可能文の一種です。実行されると、名前 name の関数 が定義され、終了ステータスとして 0 を返します。command は 通常、 “{” と “}” で囲まれたリストです。

local コマンドを用いて関数に局所的な変数を宣言することができます。 これは関数定義中の最初の文で行わなければなりません。構文は次のとおりです。

local [variable ...] [-]

local コマンドは、組み込みコマンドとして実装されています。

変数を局所変数にする場合、関数を呼び出した環境に同じ名前の変数があれば、 新しい局所変数は値と export、readonly フラグを引き継ぎます。もし同じ名前の 変数がなければ、局所変数は初期値を持ちません。シェルは動的スコープ を用います。すなわち、関数 f に局所的な変数 x を作成し、関数 f から関数 g を呼び出した場合、関数 g 内部での変数 x に対する操作は大域変数 x ではなく、関数 f で宣言された変数 x への操作となります。

特殊パラメータのうち局所宣言できるのは “-” だけです。 “-” を 局所宣言すると、関数内で set コマンドを用いてシェルオプションを 変更しても、関数が終了するとそれらのオプションは元の値に戻ります。

return コマンドの文法は以下のとおりです。

return [exitstatus]

return は現在実行中の関数を終了させます。 return は組み込みコマンドとして実装されています。

  変数とパラメータ
シェルはパラメータの集合を管理しています。名前を持つパラメータを 変数と呼びます。シェルは、起動時にすべての環境変数をシェル変数に取り込みます。 新たな変数は、次の形式によって設定できます。

    name=value

ユーザが設定する変数は、アルファベット、数字、アンダスコア (_) のみ からなる名前を持つ必要があります。また、最初の文字が数字であっては いけません。 パラメータは、以下に示す数字または特殊記号により参照することもできます。

  位置パラメータ
位置パラメータは、0 より大の数字によって参照されるパラメータです。シェルは 位置パラメータの初期値としてシェルスクリプト名に続く引数を設定します。 組み込みコマンド set により再設定や消去ができます。

  特殊パラメータ
特殊パラメータは、以下に挙げる特殊文字のいずれかにより参照される パラメータです。各パラメータの値の説明を各文字の後ろに示します。

*   位置パラメータ 1,2,... に展開されます。ダブルクォート文字列内部で展開 される場合、展開結果は各位置パラメータの間を変数 IFS の先頭の文字 ( IFS が設定されていない場合は <空白文字> ) で区切った単一の文字列になります。

@   位置パラメータ 1,2,... に展開されます。ダブルクォート引用の内部で展開 される場合、各位置パラメータは別々の引数となります。 もし、位置パラメータが設定されていない場合には、 @ の展開結果は 0 個の引数となります (ダブルクォート引用の内部であっても)。 すなわち、$1 が “abc” 、$2 が “def ghi” であった場合、 "$@" は 次の 2 つの引数に展開されます。

        "abc"   "def ghi"

#   位置パラメータの数に展開されます。

?   最後に実行したパイプラインの終了ステータスに展開されます。

-   (ハイフン) 現在のオプションフラグ (1 文字オプション名をつないだ文字列) に展開されます。起動時に指定されたもの、組み込みコマンド set で指定した もの、シェルが暗黙に設定したもののすべてを含みます。

$   起動されたシェルのプロセス ID に展開されます。 サブシェルも親シェルと同じ値を持ちます。

!   現在のシェルが最後にバックグラウンドで実行したコマンドのプロセス ID に 展開されます。パイプラインの場合、パイプラインの最後のコマンドの プロセス ID になります。

0   (ゼロ) シェルの名前またはシェルスクリプト名に展開されます。

  単語展開
本節では、単語に対して適用されるさまざまな展開について説明します。あとで 述べるように、すべての展開がすべての単語に対して適用されるわけではありません。

単一の単語に対して適用されたチルダ展開、パラメータ展開、コマンド置換、 数式展開、クォート削除の結果は単一のフィールドになります。単一の単語が 複数のフィールドに分割される可能性があるのは、フィールド分割または パス名展開の場合だけです。この規則の唯一の例外は、ダブルクォート中の パラメータ @ の展開です (前述)。

単語展開の順序は以下のとおりです。

1.  チルダ展開、パラメータ展開、コマンド置換、数式展開 (これらはすべて 同時に行われます)

2.  変数 IFS の値が空でなければ、(1) の結果の各フィールドに対して フィールド分割が行われる

3.  パス名展開 ( -f オプションが無効の場合)

4.  クォート削除

文字 “$” はパラメータ展開、コマンド置換、数式評価を行うきっかけになります。

  チルダ展開 (ユーザのホームディレクトリ名への置換)
引用されていないチルダ文字 (~) で始まる単語は、チルダ展開の対象になります。 チルダ文字からスラッシュ文字 (/) または単語の終端までのすべての文字がユーザ名 とみなされ、そのユーザのホームディレクトリに置換されます。もしユーザ名が 省略された場合 (たとえば ~/foobar)、チルダ文字は変数 HOME の値 (現在のユーザのホームディレクトリ) に置換されます。

  パラメータ展開
パラメータ展開の形式は以下のとおりです。

    ${expression}

ここで、expression は対応した “}” までのすべての文字です。対応する “}” を調べる際に、バックスラッシュ文字によりエスケープされたり、クォート文字に 狭まれた “}” や、数式展開に埋め込まれている文字や、コマンド置換や変数展開中に ある文字は調べる対象になりません。

パラメータ展開の形式のうちもっとも単純なものは以下のとおりです。

    ${parameter}

そのパラメータに値が存在する場合、その値に置き換えられます。

パラメータ名やシンボルを中括弧 ({}) で囲んでも構いません。この中括弧は、 数字 2 文字以上からなる位置パラメータの場合や、パラメータ名の直後に パラメータ名の一部であるとみなし得る文字が続く場合を除き、 省略可能です。ダブルクォート引用中のパラメータ展開は以下 のようになります。

1.  パラメータ展開を行った結果の単語に対しては、パス名展開は適用されません。

2.  パラメータが特殊パラメータ @ の場合を除き、フィールド分割は適用されません。

さらに、以下の形式を用いることにより、パラメータ展開の結果に修正を加える ことができます。

${parameter:-word}
    デフォルト値への置換: パラメータ parameter が設定されていないか空の値 を持つ場合、word を展開した結果に置換されます。さもなければ、パラメー タ parameter の値に置換されます。

${parameter:=word}
    デフォルト値の代入: パラメータ parameter が設定されていないか空の値を持つ場合、word を展開 した結果が parameter に代入されます。最終的にパラメータ parameter の値 に置換されます。位置パラメータや特殊パラメータは、この方法で代入すること はできません。

${parameter:?[word]}
    空か設定されていないときにエラーとする: パラメータ parameter が設定されていないか空の値を持つ場合、word を展開 した結果 (word が省略された場合にはパラメータが設定されていないことを表す デフォルトのメッセージ) が標準エラー出力に書き出され、 シェルは非 0 の終了ステータスで終了します。 それ以外の場合、パラメータ parameter の値に置換されます。対話的シェルの場合は 必ずしも終了しません。

${parameter:+word}
    代替値の使用: パラメータ parameter が設定されていないか空の値を持つ場合、空の値に 置換されます。さもなければ、word を展開した結果に置換されます。

    以上のパラメータ展開において、`:' を用いた場合はパラメータが設定されていない かまたは空の値であることが検査され、`:' を省略するとパラメータが 設定されていないことのみを検査します。

${#parameter}
    文字列の長さ: パラメータの値の (文字列としての) 長さに置換されます。

以下の 4 通りのパラメータ展開は部分文字列切り出し処理を行います。各場合 において、パターンは正規表現ではなく、パターンマッチ記法 ( シェルパターン の項を参照) が用いられます。パラメータが * または @ の場合、展開の結果 がどうなるかは規定しません (unspecified)。 パラメータ展開全体をダブルクォートで囲んでも パターンは引用されません。中括弧のなかで引用することにより パターンを引用することができます。

${parameter%word}
    最短後置パターンの削除: まず word が展開され、その結果をパターンとして扱います。 パラメータ parameter の右から、パターンに一致する最短の部分を削除した文字列に 置換されます。

${parameter%%word}
    最長後置パターンの削除: まず word が展開され、その結果をパターンとして扱います。 パラメータ parameter の右から、パターンに一致する最長の部分を削除した文字列に 置換されます。

${parameter#word}
    最短前置パターンの削除: まず word が展開され、その結果をパターンとして扱います。 パラメータ parameter の左から、パターンに一致する最短の部分を削除した文字列に 置換されます。

${parameter##word}
    最長前置パターンの削除: まず word が展開され、その結果をパターンとして扱います。 パラメータ parameter の左から、パターンに一致する最長の部分を削除した文字列に 置換されます。

  コマンド置換
コマンド置換により、コマンド名自身をコマンドの出力で置き換えることができます。 コマンド置換は、以下のように、コマンド command を囲った場合、

    $(command)

またはバッククォートバージョン

    `command`

とした場合に行なわれます。 シェルは、コマンド command をサブシェルの環境で実行し、command が標準出力 に出力したものから最後の改行文字を削除した結果で置換します。 最後以外の 改行は削除しません。ただし、フィールド分割の際に、 IFS の値や引用のされかたによっては、 ここで残った改行文字が結局は空白に置換されることもあります。

  数式展開
数式展開とは、数式を評価し、その値に置換する仕組みです。数式展開の形式は以下 のとおりです。

    $((expression))

数式 expression は、その中のダブルクォート文字が特別扱いを受けないという 点を除いては、ダブルクォート文字で囲まれている文字列と同様に扱われます。 シェルは expression 中のすべてのトークンにパラメータ展開、コマンド置換、 クォート削除を適用します。

次にシェルはその結果を数式として扱い、その値に置換します。

  空白文字による分割 (フィールド分割)
パラメータ展開、コマンド置換、数式展開のあと、シェルは展開結果を調べて、 ダブルクォートの外にある部分に対してフィールド分割を適用します。 その結果、複数のフィールドになる場合もあります。

シェルは、変数 IFS に設定されている文字それぞれ区切り文字とみなし、 パラメータ展開の結果、およびコマンド置換の結果をフィールドに分割します。

  パス名展開 (ファイル名生成)
-f フラグが設定されていなければ、フィールド分割が行われたあと、ファイル名生成 が行われます。各単語は、スラッシュで区切られたパターンの列であるとみなさ れます。パス名展開処理において、単語は、条件を満たすファイル すべてのファイル名の列で置換されます。この各ファイル名は、単語の 各パターン部分を、そのパターンに一致する文字列に置換することで 生成されるものです。 これには 2 つの制限があります: まず、パターンはスラッシュを含む文字列には 一致しません。次に、パターンは、そのパターンがピリオドで始まらないかぎり、 ピリオドで始まる文字列に一致しません。 次節では、パス名展開と case コマンドで用いられるパターンについて説明します。

  シェルパターン
パターンは、通常の文字とメタキャラクタからなります。通常の文字は、 その文字そのものに一致します。 メタキャラクタは “”!, “*”, “”?, “[” です。これらの文字を引用 すると、各々の特殊な意味を失います。コマンド置換や変数置換において、 ドル記号やバッククォート文字がダブルクォート文字の中にない場合には、 変数の値やコマンドの出力の中に、これらの特殊な文字が存在するかどうかが 調べられ、それらがあれば、メタキャラクタとして扱われます。

アスタリスク文字 (*) は、どのような文字列とも一致します。 クエスチョンマーク文字 ()? は、任意の文字 1 文字と一致します。 左大括弧 ([) は文字クラスを開始します。 文字クラスの最後は右大括弧 ()] です。 “”] がない場合は、 “[” は文字そのものに一致し、文字クラスの開始とは見なされません。文字 クラスは大括弧内に出現するすべての文字に一致します。 マイナス記号を用いれば、文字の範囲を指定することができます。 文字クラスの最初にエクスクラメーションマーク ()! を置くことで、 文字クラスの意味を反転させることができます。

文字クラスに文字 “”] を含めるには、 “”] を文字クラスの最初 ( “”! を置く場合はそのあと) に置きます。 文字クラスに “-” を含めるときも同様で、 リストの最初もしくは最後に置きます。

  シェル組み込みコマンド
本節では、別プロセスでは実行できない処理を行なうために組み込まれている コマンドを列挙します。 さらに、組み込みバージョンの printf(1) と test(1) が効率を上げるために提供されています。

:   終了ステータス 0 (真) を返すヌルコマンドです。

. file
    指定されたファイル file に記述されたコマンドがシェルに読み込まれ、 実行されます。 file に “/” 文字を含む場合、その通りに扱われます。 そうでなければ、シェルは PATH を使用して、ファイルを検索します。 PATH を使用しても見付からない場合、カレントディレクトリを検索します。

alias [name ...]

alias
    [name=string ...] name=string が指定されている場合、シェルは名前 name を持つ値 string のエイリアスを定義します。単に “name” だけが指定された場合、 エイリアス “name” の値が表示されます。引数が指定されない場合、 alias は定義されているすべてのエイリアスの名前と値を表示します ( unalias も参照)。

bg [job ...]
    指定されたジョブ (指定されなかった場合は現在のジョブ) を、 続けてバックグラウンドで実行させます。

command cmd [arg ...]
    指定された組み込みコマンド cmd を実行します。 シェル関数を同名の組み込みコマンドでオーバライドしたい場合に有用です。

cd [directory]
    指定されたディレクトリ directory に移動します。 directory 無指定時は HOME で指定されるディレクトリに移動します。 directory がカレントディレクトリのサブディレクトリとして見付からない場合 (かつ “/”, “./”, “../” のいずれでも開始しない場合)、指定された directory を CDPATH 変数中のディレクトリリストから検索します。 CDPATH の形式は PATH と同様です。対話的シェルでは、ユーザ が指定したディレクトリと異なる場所に移動した場合、 cd は、移動先のディレクトリ名を表示します。 これは、 CDPATH の機構が動作した場合と、シンボリックリンクを辿った場合に発生します。

chdir
    cd 組み込みコマンドの別名です。

    echo [-en] string string の後に改行文字を付けて、標準出力に表示します。

    -n  最後の改行文字を抑制します。

    -e  C 風のバックスラッシュエスケープシーケンスを処理します。 echo は次の文字エスケープを理解します:

        \a  警告 (端末ベルを鳴らす)

        \b  バックスペース

        \c  最後の改行文字を抑制します (改行文字が最後の文字でない場合、行が縮んでしまうという副作用があります)

        \e  ESC 文字 (ASCII 0x1b)

        \f  フォームフィード

        \n  改行

        \r  復改

        \t  水平タブ

        \v  垂直タブ

        \\  バックスラッシュ文字

        \0nnn
            (この 0 はゼロです) 8 進数値が nnn である文字

        string がクォートで括られていない場合、 シェルからエスケープするためには、 バックスラッシュ自身をバックスラッシュでエスケープする必要があります。 例えば次の通りです:

            $ echo -e "a\vb"
            a
             b
            $ echo -e a\\vb
            a
             b
            $ echo -e "a\\b"
            a\b
            $ echo -e a\\\\b
            a\b

eval string ...
    指定されたすべての引数を空白で結合し、その結果を解析し直してから コマンドとして実行します。

exec [command [arg ...]]
    commmand が省略されない場合、そのシェルプロセスは指定されたプログラムに 置き換えられます ( command は、シェル組み込みコマンドや関数ではない、本物の プログラムでなければなりません)。 exec コマンドにおけるリダイレクトは、 永久性を持つと見なされ、 exec コマンド完了後にも引き続き効力を持ちます。

exit [exitstatus]
    シェルを終了します。 exitstatus が指定された場合、これはシェルの終了ステータスになります。 そうでない場合、直前に実行したコマンドの 終了ステータスがシェルの終了ステータスとなります。

export name ...
    それ以後にシェルから実行されるコマンドの環境に、指定された名前の変数が 含まれるようにします (変数のエクスポート)。 変数のエクスポートを取り消す唯一の方法は、変数を unset することです。 以下のように記述することで、エクスポートすると 同時に変数の値を設定することができます。

        export name=value

    引数を指定しない場合、すべてのエクスポートされている名前と値が表示されます。

    fc [-e editor] [first [last]]

    fc -l [-nr] [first [last]]

    fc -s [old=new] [first] fc 組み込みコマンドは、対話的シェルにそれ以前に入力されたコマンドの内容を、 表示、編集、再実行します。

    -e editor
        編集に際し、指定されたエディタ editor を使用します。 editor は変数 PATH を通して検索できるコマンド名です。 -e が指定されなかった場合は、変数 FCEDIT の値が用いられます。 FCEDIT が設定されていないか空に設定されている場合は EDITORの値が用いられ、それも設定されていないか空ならば ed(1) が用いられます。

    -l (ell)
        (小文字のエル) エディタを起動せずに、コマンド履歴の内容を一覧出力します。 パラメータ first と last で指定した範囲のコマンドが順に (出力の順番は -r オプションの影響を受けます) 出力されます。 各コマンドの出力の際にはコマンド番号が付加されます。

    -n  -l で一覧出力する際にコマンド番号を付加しません。

    -r  コマンド一覧時 ( -l オプション指定時) や編集時 ( -l も -s も指定されなかった場合) の順序を反転します。

    -s  エディタを起動せずにコマンドを再実行します。

    first

    last
        一覧出力や編集の対象となるコマンドを選択します。アクセス可能なコマンド の数は変数 HISTSIZE の値で決まります。 first または last 、または両方の値は、以下のいずれかの形式で指定します。

        [+]num
            正の数で、コマンド番号を指定します。コマンド番号は -l オプションで表示させて調べることができます。

        -num
            負の数は、 num 個だけ現在から遡ったコマンドを指定します。たとえば、 -1 は直前に実行されたコマンドを指定します。

        string
            文字列 string は、過去に実行されたコマンドのうち、 その文字列から始まる最新のものを指定します。 もし -s オプションが指定されて old=new が指定されていなければ、 最初のオペランドにイコール記号 を含めることはできません。

    fc コマンドの実行にあたり、以下の環境変数の影響を受けます。

    FCEDIT
        使用するエディタ名

    HISTSIZE
        アクセス可能なコマンド数

fg [job]
    指定されたジョブ job または現在のジョブをフォアグラウンドに移動します。

getopts optstring var
    POSIX に準拠した getopts コマンドです。 この getopts コマンドにより、以前の getopt(1) コマンドの必要性は減少しました。 最初の引数は文字の列です。各文字の後ろにはコロンをつけることができ、 そのオプションが引数をとることを指示します。 指定された変数に、解析され見つかったオプションが設定されます。 見つかったオプションの次の引数のインデックスはシェル変数 OPTIND に格納されます。 あるオプションが引数をとる場合、その引数はシェル変数 OPTARG に置かれます。 有効でないオプションに出くわすと、変数 var には “”? がセットされます。 getopts はオプション群の末尾に到達すると偽の値 (1) を返します。

    hash [-rv] [command ...] シェルは、コマンドの位置を保持するハッシュテーブルを維持管理しています。 hash コマンドに引数が指定されなかった場合、このテーブルの内容が出力されます。 最後に cd コマンドが実行されてから参照されていない項目には アスタリスク文字 が表示されます。 この項目は無効になっているかもしれません。

    引数を指定した場合、 hash コマンドは指定した command をハッシュテーブルから削除し ( command が関数ではない場合)、その後でそのコマンドを検索します。 -v オプションを指定した場合、 hash は発見したコマンドの位置を表示します。 -r オプションを指定した場合、 hash は関数以外のすべてのエントリをハッシュテーブルから削除します。

jobid [job]
    ジョブ job 中の各プロセスのプロセス ID を表示します。引数 job が 省略された場合、現在のジョブに対して処理を行います。

jobs
    バックグラウンドで走行中の、現在のシェルプロセスの子プロセスの 一覧を出力します。

pwd カレントディレクトリのパスを表示します。組み込みコマンド版は カレントディレクトリ名を覚えており、表示するときに再計算しないので、 組み込みコマンド版は同名のプログラムとは異なった表示をする場合があります。 このため処理は高速ですが、カレントディレクトリ の名前を変更した場合でも、組み込み版の pwd(1) は以前のディレクトリ名を表示し続けます。

    read [-p prompt] [-t timeout] [-er] variable ... -p オプションが指定され、かつ標準入力が端末の場合、 prompt をプロンプトとして表示します。 そして標準入力から 1 行入力します。行端の改行文字を削除し、行を前述の 空白文字による分割 (フィールド分割) の方法に従って分割し、各単語を、valiable... で指定する各変数に 順に代入します。 もし、指定された変数の数より分割された単語の数が多ければ、最後の変数に 残りの単語すべて ( IFS の文字を区切りにしてそれらも一緒に) が代入されます。 分割された単語の数より多くの変数が指定されていたなら、 余った変数には空文字列が設定されます。

    -r オプションが指定された場合を除き、バックスラッシュは特別に扱われます。 バックスラッシュ文字が改行文字の直前にある場合、 バックスラッシュ文字と改行文字は削除されます。 その他の文字の直前にバックスラッシュがある場合、バックスラッシュは削除され、 文字が IFS に含まれていても、 IFS の文字でないかのように扱われます。

    -t オプションが指定され、かつ入力がなされる前に timeout が経過すると、 read コマンドは値を割当てずに戻ります。 timeout 値の後にはオプションで “s”, “m”, “h” のいずれかの一文字 を付けることが出来、それぞれ秒・分・時間を陽に指定します。 どれも指定しない場合には “s” であるものとします。

    -e オプションは、古いスクリプトとの後方互換性のためだけにあります。

readonly name ...
    name で指定された変数を読み出し専用とし、あとで値を変更したり unset した りすることができないようにします。以下のように記述することで、 変数を読み出し専用と宣言するのと同時に値を設定することも可能です。

        readonly name=value

    引数が指定されない場合、 readonly コマンドは、読み出し専用になっている変数の名前の一覧を表示します。

    set [-/+abCEefIimnpTuVvx] [-/+o longname] [-c string] [-- arg ...] set コマンドは 3 通りの異なった機能を持ちます。

    引数を指定しなかった場合、短かい形式でも長い “-/+o longname” という形式であっても、 引数リストの処理 の節で説明されているように、指定されたオプションの設定またはクリアを行います。

    “--” オプションが指定された場合、 set はシェルの位置パラメータを、引き続く引数で置き換えます。 “--” オプションの後に引数が続かない場合、 すべての位置パラメータはクリアされ、 “shift $#” コマンドを実行するのと等価になります。 位置置換パラメータとして引数を指定するとき、 “--” フラグは省略可能です。 これはお勧めできません。 なぜなら、最初の引数はマイナス記号 (-) またはプラス記号 (+) で開始するかもしれないからです。 これらは、 set コマンドが、オプションの有効化または無効化の要求であると解釈してしまいます。

setvar variable value
    変数 variable に値 value を代入します。( setvar は、関数内で、パラメータとして渡された名前を持つ 変数に値を代入するためのものです。 一般に、 setvar を使うよりも

        variable=value

    と書くほうが望ましいといえます。)

shift [n]
    位置パラメータを n 回シフトします。 n を指定しない場合 1 回シフトします。 1 回のシフトにより、$2 の値が $1 に、$3 の 値が $2 に代入されます (以下同様)。また、$# の値は 1 減少します。 位置パラメータがない場合、shift は何もしません。

    trap [action] signal ... シェルが指定されたシグナル signal を受けとったときに、 action を解析し実行するように設定します。 シグナルはシグナル番号で指定します。 action は空文字列に したり、省略したりすることができます。空文字列の場合、指定されたシグナルは 無視され、省略した場合は、指定したシグナルを受けとったときデフォルトの処理を 行ないます。シェルがサブシェルを起動するとき、trap で指定された (が無視されていない) シグナルをデフォルトの動作に再設定します。 シェルが起動したときにすでに無視されるように設定されていたシグナルに対して trap コマンドを使用しても効果はありません。

type [name ...]
    各 name をコマンドとして解釈し、コマンド検索の結果を出力します。出力さ れる結果は以下のものがあります。シェルのキーワード、エイリアス、シェル の組み込みコマンド、コマンド、痕跡つきエイリアス (tracked alias)、最後に not found (見つからず) があります。エイリアスについては、エイリアス展開 の結果が出力されます。コマンドと痕跡つきエイリアスについては、そのコマンドの 完全なパス名が印刷されます。

    ulimit [-HSabcdflmnust] [limit] リソースのリミット値 (リミット値については getrlimit(2) 参照) を設定あるいは表示します。 limit が指定されている場合、指定されたリソースが設定されます。 それ以外の場合、現在のリソース設定値が表示されます。

    -H が指定された場合、ハードリミットが設定ないし表示されます。 ハードリミット値を下げることは誰にでもできますが、 それを増やすことができるのはスーパユーザだけです。 オプション -S を指定した場合はソフトリミットになります。 リミット値を表示する場合、 -S か -H のいずれか一方だけしか指定できません。 デフォルトでは、表示はソフトリミット、設定はハード/ソフトリミット両方です。

    オプション -a を指定すると ulimit コマンドは全リソースの設定値を表示します。 この場合、パラメータ limit は指定できません。

    この他のオプションは、表示あるいは設定するリソースの種類を指定するものです。 これらは互いに排他的です。

    -b sbsize
        ソケットバッファサイズの最大値。バイト単位。

    -c coredumpsize
        コアダンプファイルの最大サイズ。512 バイトのブロック単位。

    -d datasize
        プロセスのデータセグメントの最大サイズ。キロバイト単位。

    -f filesize
        ファイルの最大サイズ。512 バイトブロック単位。

    -l lockedmem
        プロセスがロックできるメモリサイズの最大値。キロバイト単位。

    -m memoryuse
        プロセスの常駐セットサイズの最大値。キロバイト単位。

    -n nofiles
        あるプロセスがオープンできるファイル記述子の最大数。

    -s stacksize
        スタックセグメントサイズの最大値。キロバイト単位。

    -t time
        各プロセスで消費できる CPU 時間の最大値。秒単位。

    -u userproc
        このユーザ ID で同時に走らせうる最大プロセス数。

umask [mask]
    ファイル作成マスクの値 ( umask(2) を参照) を、 mask で指定された 8 進数の値に設定します。引数が 省略された場合、現在のマスクの値が表示されます。

    unalias [-a] [name] name が指定された場合、指定された名前のエイリアスを削除します。 -a オプションが指定された場合、すべてのエイリアスを削除します。

unset name ...
    指定された変数または関数を unset し、エクスポートされていない状態にします。 指定された名前の変数も関数も存在する場合、変数と関数の両方が unset されます。

wait [job]
    指定されたジョブ job が終了するのを待ち、ジョブ内の最後のプロセスの 終了ステータスを返します。引数が省略された場合、すべてのジョブが終了する まで待ち、終了ステータス 0 を返します。

  コマンド行編集
sh が端末から対話的に実行されている場合、現在入力中のコマンドおよび コマンド履歴 ( 組み込みコマンド の fc 参照) を vi モードのコマンド行編集機能 により編集することができます。 このモードでは、vi のマニュアルに示されているコマンドのサブセットを用います。 コマンド “set -o vi” (または “set -V”) により vi モードが有効になり、 sh は vi の挿入モードに移行します。 vi モード中では、 挿入モードとコマンドモードの両方を自由に切り替えることが可能です。 vi モードは vi と同様であり、 <ESC> キー によりコマンドモードに移行し、コマンドモードで <return> キーを叩くことで、 行の内容がシェルに渡されます。

同様に、コマンド “set -o emacs” により emacs 風のコマンド行編集機能の サブセットを使うことができるようになります。

関連項目
builtin(1), echo(1), expr(1), printf(1), pwd(1), test(1)

歴史
sh コマンドは、 AT&T UNIX で登場しました。