SH(1)

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

書式
sh [-/+aCefnuvxIimsVEb] [-o longname] [target ...]

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

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

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

    ENV=$HOME/.shinit; export ENV

ここで、 “.shinit” のかわりに好きなファイル名を指定してかまいません。 ENV で示されるファイルは、シェルスクリプトを実行する場合や、非対話的に 実行される場合も含めて、シェルが呼び出される際に必ず実行されますので、 対話的にシェルを呼び出す際にのみコマンドを実行させたい場合には、 以下のような記述方法を用いるのがよいでしょう。 つまり、 “case” と “esac” (これらのコマンドについては後述) の間に 対話的シェルでのみ実行したいコマンドを書きます:

case $- in *i*)
# commands for interactive use only
...
esac

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

  引数リスト処理
1 文字からなるオプションはそれぞれ対応する名前を持っており、 -o オプションに 続けてその名前を記述することで、1 文字からなるオプションを指定したのと 同じ効果を得ることができます。 -o オプションで指定する名前は、オプション に関する以下の説明中で1文字オプションのあとに書いてあります。 マイナス記号 “-” でオプションを指定することは、そのオプションを 有効にすることを意味し、 プラス記号 “+” でオプションを指定することは、そのオプションを無効に することを意味します。以下のオプションは、コマンドライン引数または set(1) 組み込みコマンド (後述) により設定できます。

-a allexport
    値が代入された、すべての変数をエクスポートします (4.4alpha ではインプリメント されていません)。

-C noclobber
    すでに存在するファイルに対しては “>” リダイレクトによる上書きをしません (4.4alpha ではインプリメントされていません)。

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

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

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

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

-v verbose
    読み込んだ行を標準エラー出力に書き出します。デバッグする際に便利です。

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

-q quietprofile
    -v または -x オプションが指定された場合でも、初期化ファイルつまり /etc/profile や .profile や環境変数 ENV で指定されたファイルを読む時には適用しません。

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

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

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

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

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

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

-b notify
    バックグラウンドジョブの完了を、即座 (非同期) に報告します (4.4alpha では インプリメントされていません)。

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

制御演算子:
    & && (); ;; | || <newline>

リダイレクト演算子:
    < > >| << >> <& >& <<- <>

  クォート
クォートは、特定の文字や単語 (演算子、空白、単語等) の特殊な意味を打ち消す ために用いられます。クォートにはシングルクォートのペア、ダブルクォートのペア、 バックスラッシュの 3 種類があります。

  バックスラッシュ
バックスラッシュは、それに続く 1 文字を文字どおりに (リテラルとして) 扱うように 指示します。ただし、 <改行> は例外です。 <改行> の直前のバックスラッシュは、行の継続であるとみなされます。

  シングルクォート
シングルクォートのペアで狭まれたすべての文字はリテラルとして扱われます (シングルクォートは例外です。シングルクォートで括られた文字列中に シングルクォートを置けなくなります)。

  ダブルクォート
ダブルクォートのペアで狭まれた文字は、ドル記号 ($), バッククォート (`), バックスラッシュ (\) を除き、すべてリテラルとして扱われます。 ダブルクォート中のバックスラッシュは、直後に
    $ ` \ <改行>
がくるときにのみ、それらの文字がリテラルとして扱われることを示します。 そうでない場合、バックスラッシュ自体がリテラルとして扱われます。

  予約語
予約語はシェルにとって特別な意味を持つ単語で、行の先頭または制御演算子 の直後でのみ特別に扱われます。以下に予約語の一覧を挙げます。
! | elif | fi | while | case
else | for | then | { | }
do | done | until | if | esac

これらの意味は後述します。

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

    lf foobar <改行>

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

    ls -F foobar <改行>

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

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

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

1.  単純コマンドの前にある “name=value” 形式の単語は取り除かれ、 単純コマンドの環境に併合されます。リダイレクト演算子とその引数 (後述) は 取り除かれ、あとの処理のために保存されます。

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

3.  次節で解説するようにリダイレクトが行われます。

  リダイレクト
リダイレクトは、コマンドが読み書きする対象を変更する場合に用いられます。 一般には、リダイレクトでは、ファイルのオープン、クローズ、または、 ファイルへの参照の複写を行います。 リダイレクトは全般的に以下のようなフォーマットとなっています:

    [n] redir-op file

ここで、 redir-op は前述したリダイレクト演算子のいずれかです。 以下に、リダイレクトの例をいくつか挙げます。 [n] は省略可能な番号で、たとえば ‘3’ と書きます (‘[3]’ ではありません)。 これはファイル記述子の番号です。

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

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

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

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

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

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

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

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

[n]<> file
    標準入力 (あるいはファイル記述子 n) により、ファイル file を読み書きするよ うにします。

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

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

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

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

シェル関数が実行されるとき、シェルの全ての位置パラメータ ($0 は除きます。$0 は変更されません) にはシェル関数への引数が設定されます。 コマンドの環境として明示された変数 (関数名の直前に置かれた代入文によるもの) は、その関数だけの局所的な変数となり、指定された初期値が設定されます。 そして、関数定義内のコマンドが実行されます。 そのコマンドの実行が完了すると、位置パラメータは元の値に戻ります。 これは全て現在のシェルの中で起こります。

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

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

このドキュメントの以前のバージョンとソースコードでは、 マジックナンバなしのシェルスクリプトに対して "shell procedure" という 紛らわしい表現を何度か使っていました。

  パス検索
コマンドを検索するとき、シェルは、まず、それがシェル関数であるかどうかを 調べます。次に組み込みコマンドであるかどうかを調べます。 もし組み込みコマンドが見つからない場合は、以下の 2 つのうちのどちらかが 起こります:

1.  スラッシュを含むコマンド名は、どのような検索も行わずに単純に実行します。

2.  shell は コマンドを PATH の各要素から順に探します。 PATH 変数の値はコロン ``:'' で区切られたエントリの列でなければなりません。 各エントリは、それぞれディレクトリ名 1 つに対応します。 カレントディレクトリは、空のディレクトリ名で示すか、 ピリオド 1 つで明示的に示すことができます。

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

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

•   単純コマンド

•   パイプライン

•   リストまたは複合リスト

•   複合コマンド

•   関数定義

特に明言しない限り、コマンドの終了ステータスは最後に実行された単純コマンドの 終了ステータスとなります。

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

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

    [!] command1 [| command2 ...]

command1 の標準出力は command2 の標準入力に接続されます。コマンドの一部 であるリダイレクト演算子によって指示されたいかなるリダイレクト処理にも 先立って、標準入力、標準出力、またはその両方がパイプラインに接続されます。

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

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

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

    $ command1 2>&1 | command2

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

; または <改行> は、直前の AND-OR リスト (後述) を順次実行します。& は、 直前の AND-OR リストを非同期に実行します。

他のシェルと違い、パイプライン内の各シェルは、起動しているシェルの子になります (シェルの組み込みコマンドでない限りこうなります。組み込みコマンドの場合は 現在のシェルで実行されますが、環境変数に対する影響は取り消されます)。

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

コマンドをバックグラウンドで走らせるためのフォーマットは、 以下のようになっています:

    command1 & [command2 & ...]

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

  リスト -- 一般的な記述
リストは 0 またはそれ以上のコマンドを改行、セミコロン、アンド記号で 区切った列で、これら 3 つの記号のいずれかで終了させる (なくてもよい) ことが できます。リスト中のコマンドは並べられた順に実行されます。もし、コマンドに 続けてアンド記号が置かれている場合、シェルはそのコマンドを起動したあと、 すぐに次のコマンドの処理を開始します。その他の場合は、コマンドの終了を 待ってから次のコマンドの処理を開始します。 “&&” と “||” は 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 コマンドもこれに似ていますが、 until コマンドの場合、 単語 while の部分が単語 until になり、これは最初のリストの終了ステータスが 0 に なるまで 2 つのリストを繰り返し実行します。

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

    for variable in word...
    do   list
    done

word は展開され、変数 variable に各単語を順に設定しながらリストを 繰り返し実行します。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; }

のいずれかの方法によりグループ化することができます。 最初の形式では、コマンドはサブシェル上で実行されます。 組み込みコマンドを (list) のグループに入れると、現在のシェルには影響が 出ません。 2 番目の形式では別のシェルを fork しないので、少しだけ効率がよくなります。 この両方のグループ化コマンドにより、その出力をまるで 1 つのプログラムが 出力したようにリダイレクトすることが可能になります。

    { 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

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

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

  特殊パラメータ
特殊パラメータは、以下の特殊文字のいずれかにより参照されるパラメータです。

*   位置パラメータ 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}

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

${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) コマンドで用いられるパターンについて記述します。

  シェルパターン

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

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

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

  組み込みコマンド
本節では、別プロセスでは実現できない処理を行うために組み込まれているコマンド を列挙します。さらに、効率を上げるために組み込みになっているコマンド (たとえば printf(1), echo(1), test(1) 等) もあわせて列挙します。

:   戻り値 0 (真) を返すヌルコマンドです。

. file
    指定したファイル内のコマンドが、その shell によって実行されます。

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

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

command command arg...
    指定された組み込みコマンドを実行します (組み込みコマンドと同じ名前のシェル関数 がある場合に便利です)。

cd [directory]
    指定されたディレクトリに移動します (無指定時は $HOME )。 cd コマンドの環境に CDPATH 変数があるか、シェル変数 CDPATH が設定されていて、かつ 指定されたディレクトリ directory がスラッシュから始まっていないなら、 CDPATH に列挙されたディレクトリ以下に指定されたディレクトリ directory がないか検索されます。 CDPATH の形式は PATH と同様です。対話的シェルでは、ユーザが指定した ディレクトリと異なる場所に移動した場合、移動先のディレクトリ名 を表示します。これは、 CDPATH の機構が動作した場合と、シンボリックリンクを辿った場合に発生します。

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

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

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

export name...

export -p
    それ以降にシェルから実行されるコマンドの環境に、指定された名前の変数が 含まれるようにします (エクスポート)。変数のエクスポートを取り消す唯一の方法は、 変数を unset することです。以下のように記述することで、エクスポートすると 同時に変数の値を設定することができます。 -p オプションを指定すると、出力が、非インタラクティブシェル時に便利なように 整形されます。

        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 (エル)
        エディタを起動するのではなく、コマンド履歴の一覧を出力します。 パラメータ first と last で指定した範囲のコマンドが順に出力されます。 この出力の順番は -r オプションの影響を受けます。また、 各コマンドの出力の際にはコマンド番号が付加されます。

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

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

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

    first

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

        [+]number
            正の数はコマンド番号を示します。コマンド番号は -l オプションで表示されるものです。

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

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

    fc コマンドは、以下の環境変数の影響を受けます:

    FCEDIT
        使用するエディタ名

    HISTSIZE
        アクセスできるコマンド数

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

getopts optstring var
    POSIX の getopts コマンドです。 Bell Labs のものを起源とする getopt(1) と混同しないようにしてください。

    第 1 引数は文字の並びで、それぞれにコロンがつくと、そのオプションが引数をとる ことを表します。指定した変数には、そのオプションを解析したものが入ります。

    getopts コマンドは、古い getopt(1) ユーティリティにおける空白を含む引数の扱いを軽視します。

    組み込みコマンド getopts は、パラメータリストからオプションとその引数を得るために使うことができます。 起動すると、 getopts はオプション文字列をもとに次のオプションの値を取り出して、 var で指定したシェル変数に入れ、そのインデクスをシェル変数 OPTIND に置きます。 シェルが起動された時は OPTIND は 1 に初期化されます。 オプションが引数をとる場合、 getopts はその引数をシェル変数 OPTARG に置きます。 optstring で許されていないオプションの場合、 OPTARG は unset されます。

    optstring はオプション文字列です (getopt(3) 参照)。 もし、文字の後にコロンがついていれば、そのオプションは引数を持つことが期待 されます。このとき、空白で区切られていても区切られていなくても構いません。 もし期待したオプション文字が見つからなかった場合、 getopts は変数 var に “”? を設定し、それから OPTARG を unset して、出力を標準エラーに書き出します。 optstring の最初でコロンを指定すると、全てのエラーが無視されます。

    オプションの最後に到達したときは、0 でない値が返ります。 引数の残りがない場合、 getopts は var に特殊なオプション “--” を設定し、そうでなければ var に “”? を設定します。

hash -rv command...
    シェルは、コマンドの位置を保持したハッシュテーブルを維持管理しています。 hash コマンドに引数が指定されなかった場合、このテーブルの内容が出力されます。 最後に cd コマンドが実行されてから参照されていない内容には アスタリスク文字 (“*”) がつきます。 このマークがついたエントリは不正である可能性があります。

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

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

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

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

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

    デフォルトでは、 -r を指定しない限りバックスラッシュ “\” はエスケープキャラクタとして働き、 その直後にある文字はその文字そのものとして解釈されます。 バックスラッシュの直後に改行がある場合、バックスラッシュと改行は削除されます。 その他の文字の直前にバックスラッシュがある場合、そのバックスラッシュと改行は 削除されます。

readonly name...

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

        readonly name=value

    引数が指定されない場合は、読み出し専用になっている変数の名前の一覧が表示され ます。 -p オプションを指定すると、出力が、非インタラクティブシェル時に便利なように 整形されます。

set [{ -options | +options | -- }] arg... 引数を指定しなかった場合、すべてのシェル変数の名前と値の一覧を表示します。

    オプションが指定された場合、指定されたオプションフラグを、``引数リスト処理'' の節で説明してある方法で、設定あるいは解除します。

    第 3 の用法は、シェルの位置パラメータを変更することです。オプションの 設定を変更せずに位置パラメータのみを変更したい場合は set コマンドへの最初 の引数として “--” を指定します。もし arg が指定されなければ、 全ての位置パラメータはクリアされます “shift $#” を実行することと等価です)。

setvar variable value
    変数に値を代入します (一般に、setvar を使うよりも variable=value と書くほうが 望ましいといえます。setvar は、関数内で、パラメータとして渡された名前を持つ変数 に値を代入するためのものです。例えば関数内で setvar $1 value とすることにより、 第 1 引数として渡された名前を持つ変数に値を代入できます)。

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

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

type [name ...]
    各 name をコマンドであると判断し、そのコマンドの検索結果を表示します。 結果は、shell keyword, alias, shell builtin, command, tracked alias, not found などに分類されます。エイリアスの場合は、そのエイリアスの 展開結果が表示されます。コマンドと tracked alias の場合は、その コマンドの完全なパス名が表示されます。

ulimit
    [-H - -S] [-a - -tfdscmlpn [value]] プロセスに対するハードリミットもしくはソフトリミットの問い合わせや 設定を行います。 ハードリミット (どのプロセスも違反することはできず、 いったんその値より下がると、そのリミット値を越えることができなくなります) かソフトリミット (プロセスに対してシグナルは送りますが、 必ずしも kill されるわけではなく、リミットを越えることも許されます) かの選択は以下のフラグで指定します:

    -H  ハードリミットの設定や問い合わせを行います。

    -S  ソフトリミットの設定や問い合わせを行います。 -H と -S のどちらも指定されなかった場合には、 ソフトリミットが表示されたり両方のリミットが設定されたりします。 両方指定された場合は、最後に指定したものが勝ちます。

    リミットの問い合わせや設定を行うには、以下のフラグのうちの 1 つを選択します:

    -a  現在の全リミットを表示します

    -t  CPU 時間の上限を表示もしくは設定します (単位は秒です)

    -f  作成するファイルのサイズの上限を表示もしくは設定します (単位は 512 バイトブロックの個数です)

    -d  プロセスのデータセグメントの上限を表示もしくは設定します (単位はキロバイトです)

    -s  プロセスのスタックサイズの上限を表示もしくは設定します (単位はキロバイトです)

    -c  生成されるコアダンプのサイズの上限を表示もしくは設定します (単位は 512 バイトブロックの個数です)

    -m  プロセスが使用する物理メモリの量の総計の上限を表示もしくは設定します (単位はキロバイトです)

    -l  プロセスが mlock(2) でロックできるメモリの量の上限を表示もしくは設定します (単位はキロバイトです)

    -p  ユーザが一度に持つことができるプロセスの数の上限を表示もしくは設定します

    -n  プロセスが一度に open することができるファイルの数の上限を 表示もしくは設定します

    これらがどれも指定されなかった場合は、ファイルサイズのリミット値が 表示もしくは設定されます。 値が指定された場合は、そのリミット値がその値に設定されます。 指定されなかった場合は、現在のリミット値が表示されます。

umask [mask]
    umask の値 (umask(2) を参照) を、指定された 8 進数の値に設定します。引数が 省略された場合、現在の umask の値が表示されます。

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

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

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

  コマンドライン編集
sh が端末から対話的に実行されている場合、現在入力中のコマンドおよび コマンド履歴を vi モードのコマンドライン編集機能により編集することができます。 このモードは、 vi のマニュアルに示されているコマンドのサブセットです。 ‘set -o vi’ により vi モードが開始され、挿入モードに移行します。vi モード中では、 挿入モードとコマンドモードの両方を自由に切り替えることが可能です。 本マニュアルではコマンドライン編集についてすべてを記述することはしません。 いずれドキュメントが用意されるでしょう。vi モードは vi と同様であり、 <ESC> によりコマンドモードに移行し、コマンドモードで <改行> を入力することで、行の内容がシェルに渡されます。

環境変数

HOME
    login(1) によって、パスワードファイル (passwd(4)) 内にあるそのユーザのログインディレクトリが自動的に設定されます。 この変数は組込みコマンド cd のデフォルト引数としても機能します。

PATH
    実行可能ファイルのデフォルトの検索パスです。 パス検索 のセクションも参照してください。

CDPATH
    組込みコマンド cd が使用する検索パスです。

MAIL
    メールファイルの名前で、新しいメールが到着したかどうかの判断のために このファイルがチェックされます。 MAILPATH のほうが優先されます。

MAILCHECK
    shell が MAILPATH または MAIL で指定されたファイルに対するメールの到着をチェックする間隔を秒で指定します。 0 の場合、プロンプトの表示のたびにチェックされます。

MAILPATH
    コロン “”: で区切られたリストで、shell がメールの到着を調べるために使います。 この環境変数は MAIL の設定よりも優先されます。 一度に監視できるメールボックスの最大数は 10 です。

PS1 メインのプロンプト文字列です。デフォルトは、スーパユーザでなければ “$ で、スーパユーザならば” “# です。”

PS2 2 番目のプロンプト文字列です。デフォルトは “> です。”

IFS 入力フィールドセパレータです (Input Field Separators)。 通常は <空白> <タブ> <改行> に設定されます。詳細は 空白分割 のセクションを参照してください。

TERM
    そのシェル用のデフォルトの端末設定です。これは、そのシェルの子に継承されます。 ヒストリ編集モードで使用されます。

HISTSIZE
    そのシェルのヒストリバッファの行数です。

関連ファイル

$HOME/.profile

/etc/profile

関連項目
csh(1), getopt(1), ksh(1), login(1), test(1), getopt(3), passwd(4), profile(4), environ(5)

歴史
sh コマンドは AT&T UNIX で登場しました。 しかし、メンテナンスできなかったので、我々はこの版を書きました。

診断
syntax エラーなどのエラーがシェルで検出されると、そのシェルは 非 0 のステータスで終了します。シェルがインタラクティブシェルでない 場合には、そのシェルファイルの実行が中断されます。 インタラクティブシェルであれば、最後に実行したコマンドの終了ステータス が返るか、もし組込みコマンド exit が数値の引数つきで実行された場合には その値が返ります。

バグ
setuid されたシェルスクリプトは著しくセキュリティ上の危険を伴うため、 どんなコストを費やしてでも避けるべきです。