Museum

Home

Lab Overview

Retrotechnology Articles

⇒ Online Manual

Media Vault

Software Library

Restoration Projects

Artifacts Sought

SH(1)  —  NEWS-OS Programmer’s Manual

名称

sh, for, case, if, while, :, ., break, continue, cd, eval, exec, exit export, login, read, readonly, set, shift, times, trap, umask, wait − コマンド言語

形式

sh [ −ceiknrstuvx/ ] [ arg ] ... 

解説

sh は端末あるいはファイルから読み込んだコマンドを実行する プログラミング言語です。 shell への引数の意味は 起動 を参照してください。

コマンド
単純コマンド とは、 ブランク (タブ または スペース)で区切られたブランクのない word の列です。 最初の word は、 実行されるコマンド名を示します。 残りの引数は、 以下で特別に記載しない限り起動されるコマンドに対する引数となります。 コマンド名は、 引数 0 として渡されます (execve(2) を参照) 。 単純コマンドの返す 値 は、 それが正常終了する時はその終了ステータスであり、 異常終了時は 200+ステータス です (ステータス値の一覧は sigvec(2) を参照)。 パイプラインとは、 | で区切られた 1つ以上の コマンド の列です。 最後のコマンドを除き、 コマンドの標準出力は pipe(2) によって次のコマンドの標準入力となります。 それぞれのコマンドは、 別プロセスとして実行され、 シェルは最後のコマンドの終了を待ちます。 リスト とは、 ; あるいは &、 &&、 || で区切られた 1つ以上のパイプラインの列です。 ; または & で終わっているものでもかまいません。 ; と & は同一優先度を持ち、 &&、 || よりは優先度が低くなります。 && と || は優先度が同じです。 ; は順次実行を行います。 & は前のパイプラインの実行終了を待つことなく実行します。 && (||) は、前の パイプライン が値 0 (0 以外) を返したときのみ後ろの リスト を実行します。 コマンドの区切りとしては ; の代わりに NL (ニューライン)も使用できます。 コマンドとは、 単純コマンドまたは次のいずれかです。 コマンドが返す値は最後に実行された単純コマンドが返す値となります。

for name [in word ...] do list done
for コマンドが実行されるごとに、 word リスト中の次の word が name にセットされ、 list が実行されます。 in word ... が省略されると、 in "$@" とみなされます。 word リストが無くなると実行は終了します。

case word in [pattern [ | pattern ] ... ) list ;;] ... esac
case コマンドは、 word とマッチする最初の pattern に対応する list を実行します。pattern の形式は、 ファイル名の生成で用いられたものと同じです。

if list then list [elif list then list] ... [else list] fi
if の後の list が実行され、 もし値 0 の終了ステータスが返されると、 最初の then list が実行されます。 そうでなければ、 elif list が実行され、 その値が 0 なら、 次の then list が実行されます。 そうでなければ、 else list が実行されます。

while list [do list] done
while コマンドは、 while list を繰り返し実行し、 もしその値が 0 のときは do list を実行します。 そうでなければ、 ループは終了します。 while コマンドが返す値は do list で実行された最後のコマンドの終了ステータスとなります。 ループ終了条件を反転させるために、 while の代わりに until を使用することができます。

( list )
サブシェル中で list を実行します。

{ list }
list が単に実行されます。 以下の word は、 引用符で囲まれないときには、 コマンドの最初の word として認識されます。

if then else elif fi case for while until do done {}

コマンドの置き換え
逆引用符 (``) で囲まれたコマンドからの標準出力は、 word の一部または word 全体として使用できます。 ただし、 最後の NL (ニューライン)は取り去られます。

パラメータの置き換え
文字 $ は置き換えのできるパラメータを取り出すのに使われます。 位置パラメータは set コマンドによって値を設定することができます。 name は次のような形式でセットされます。

name=value [ name=value ] ... 

${parameter}
parameter は文字、 数字群または下線 (以上 name 用)、数字あるいは文字 ∗ @ # ? − $ ! の列です。 パラメータにもし値があれば置き換えられます。 中かっこ { } は parameter の後に、 そのパラメータの一部とは解釈されない英字、 数字、 または下線が伴うときのみ必要になります。 parameter が数字ならば、 それは位置パラメータとなります。 parameter が ∗ または @ の場合、 $1 から始まるすべての位置パラメータが空白で区切られて置き換えられます。 パラメータ $0 にはシェルが起動された時の引数 0 がセットされます。

${parameter−word}
parameter が設定されているならその値に置き換わります。 そうでなければ、 この式は word で置き換わります。

${parameter=word}
parameter が設定されていなければ、 parameter にword をセットし、この式はその parameter の値で置き換えられます。 位置パラメータをこのようにして設定することはできません。

${parameter?word}
parameter が設定されていれば、 その値に置き換えます。 そうでなければ、 word を表示し、 シェルから抜け出ます。 word が省略されると標準メッセージが表示されます。

${parameter+word}
parameter が設定されているなら、 word に置き換わります。そうでなければナル(空の文字列)に置き換わります。 上記において word は置き換わるべき文字列として使われない限り、 評価されません。
 (したがって、 たとえば echo ${d−´pwd´}では、 d がセットされていない場合だけ、 pwd が実行されます)。 以下のパラメータはシェルによって自動的にセットされます。

# 位置パラメータ数 (10進数)

− シェル起動時または set コマンドにより指定されたフラグ

?  順次実行されたコマンドのうち最終コマンドの返す値 (10進数)

$ 当シェルのプロセス番号

!  起動された最後のバックグラウンドコマンドのプロセス番号

以下のパラメータはシェルにより使用されますがシェルでセットはできません。

HOME
cd コマンドの引数のデフォルト値 (ホームディレクトリ) 。

PATH コマンドのサーチパス (実行の項を参照) 。

MAIL もし、 この変数にメールファイルの名称がセットされていると、 シェルはその指定ファイル中にメールが届いたことを知らせます。

PS1 第1 プロンプト文字です。 デフォルトは ‘$ ’ です。

PS2 第2 プロンプト文字です。 デフォルトは ‘> ’ です。

IFS フィールド区切り記号です。 通常は、スペース および タブ、 改行 です。 IFS は sh がルートで実行されているとき、 または有効なユーザIDが実際のユーザIDと異なるとき無視されます。

ブランクの解釈
パラメータとコマンドの置き換え処理後、 置き換えの結果はフィールドの区切り記号 ($IFS で見つけられる)があるかスキャンされます。 もしそれがあると、 その区切り記号のところで異なる引数として分離されます。 明白なナル引数 ("" または ´´)  は残りますが (値の設定されていない パラメータ の置き換えから生じる) ナル引数は取り去られます。

ファイル名の生成
置き換え処理後、 それぞれのコマンド word は、 その中に文字 ∗ および ?、 [ があるかスキャンされ、 もしあるとその word は pattern とみなされます。 word は、 pattern にマッチする、 アルファベット順にソートされたファイル名に置き換えられます。 もし pattern とマッチするファイル名が見つからないと、 その word は変更されずそのままとなります。 ファイル名の初めまたは / の直後にある文字 .  または / は、 ∗ や ? とはマッチしないので明示しなければなりません。

∗ ナル文字列を含む任意の文字列とマッチします。

?  任意の 1文字とマッチします。

[…] 囲まれた文字のうち任意の 1 文字とマッチします。 − で区切られた文字のペアは、 ペア間のコード順の任意の文字とマッチします。

引用符の使用
次の文字はシェルにとって特別な意味を持ち、 引用符で囲まれない限り (クォートされない限り) word の終了であることを意味します。
    ;   &   (   )   |   <   >   newline   space   tab 単一文字は \ を先頭につけて クォート できます。 \. \newline は無視されます。 シングルクォート (´´) で囲まれた全文字はシングルクォート (’) を除いてクォートされます。 ダブルクォートで囲まれた全文字 ("") は \ および  ’、”、$ を除いてクォートされます。 その中ではパラメータやコマンドの置換が起こります。 したがって、 \ を使って、\ および ’、"、$ を引用しなくてはなりません。
なお、
"$∗" は  "$1 $2..." と等価で、
"$@" は  "$1" "$2"...  と等価です。

プロンプトの表示
会話処理で使うと、 シェルはコマンドを入力する前に PS1 の値をプロンプト文字として使います。 ニューラインを入力しても、 コマンドを完全な形にするためにまだ入力を必要とする場合、 第2 のプロンプト文字  ($PS2) が現れます。

入力/出力
コマンドが実行される前に、 シェルが解釈する特別な記号を使って、 入力と出力のリダイレクトを行うことができます。 以下の記号は、 単純コマンド内の任意の位置にあってもよく、 コマンド に先行または後行してもよく、 かつ起動するコマンドには渡されることはありません。 または、 word または digit が使用される前に置きかえが起こります。

<word
ファイル word を標準入力とします (ファイル記述子 0)。

>word
ファイル word を標準出力とします (ファイル記述子 1)。 ファイルが存在しない場合には新たに作られます。 ファイルが存在している場合には、 初めにサイズ 0 にされます (内容が失われる)。

>>word
ファイル word を標準出力として使用します。 ファイルが存在する場合には、 出力はそれに追加されます (EOF を探して)。 そうでなければ、 file を作ります。

<<word
シェルは word と同じ行、 あるいは EOF までを、 入力として読み込みます。 その入力した結果のデータが標準入力となります。 もし word のうち任意の文字がクォートされると、 入力ドキュメントの文字に対する解釈は行われません。 そうでないと、 パラメータとコマンドの置換が起こり、 \newline は無視され、 文字 \ および $、 ’ 、 word の最初の1文字 をクォートするために \ が使用されます。

<&digit
標準入力がファイル記述子 digit から複製されます (dup(2) を参照) 。 同様に、 標準出力に対しては > を使います。

<&− 標準入力はクローズされます。 同様に、 標準出力に対しては > を使用します。 もし、 上記のうちいずれも数字が先行すると、 リダイレクトされるファイル記述子は (デフォルトの 0 または 1 の代わりに) 指定されたものになります。 たとえば、
    ... 2>&1 は,ファイル記述子 2 をファイル記述子 1 の複製になるようにします。 もしコマンドの後ろに & があると コマンドに対するデフォルトの標準入力は、 空のファイル (dev/null) になります。 そうでない場合は、 コマンド実行のための環境は、 入力/出力の指定により修正された起動シェルのファイル記述子を含んでいます。

環境

環境とは、 通常の引数リストと同様、 実行するプログラムに渡される name と値(value)がペアになったリストです。 execve(2) および environ(7) を参照してください。 シェルは、 種々の形態で環境とかかわり合います。 起動時、 シェルは環境をスキャンし、 見つかったそれぞれの name に対する parameter を作成し、 それに対応する値を与えます。 実行されるコマンドは同じ環境を受け継ぎます。 もし、 ユーザがこれらの parameter の値を変更したり、新しいものを作ったりしても、 export コマンドを使ってそのシェルのパラメータを環境に組み入れない限り、 これらは環境に対し影響を与えません。 起動されたコマンドに渡される環境は、 シェルによって元々引き継がれて修正されなかった name と値のペアと、 それに加えて、 export コマンド中で記述されるべき修正または追加の行われたペアとなります。 単純コマンド に対する環境は 1個以上の パラメータ の代入式をコマンドの前に指定することによって与えられます。 したがって、 次の 2つの式は等価です。

TERM=450 cmd args
(export TERM; TERM=450; cmd args) もし −k フラグが set されると、 すべて のキーワード引数は、 たとえそれらがコマンド名の後に現れても環境に置かれます。 次の例では、最初は ’a=b c’をプリントし、 後のほうは ‘c’ を表示します。

echo a=b c
set −k
echo a=b c

シグナル
コマンドの後に & を付けると、 起動したコマンドに対する INTERRUPT と QUIT シグナルは無視されます。 そうでなければ、 シグナルは、シェルがその親から引き継いだ値を持ちます (trap コマンドも参照)。

実行
コマンドが実行されるごとに、 上述した置き換えがなされます。 以下に記述されている特殊コマンド以外のコマンドに対しては、 新しいプロセスが生成され、 execve(2) を経由してそのコマンドを実行しようとします。 シェルパラメータ $PATH はコマンドを格納している ディレクトリを示すサーチパスを定義します。 サーチされるディレクトリはコロン (:) で区切って指定します。 デフォルトのパスは :/bin:/usr/bin:/usr/sony/bin です。 コマンド名が / を含む場合は、 サーチパスは使われません。 そうでない場合、 サーチパスで指定されたディレクトリに、 コマンド名と同一名称の実行可能ファイルがあるかサーチされます。 もし見つかったファイルが実行可能ファイル属性を有していながら、 a.out 形式ファイルでなければ、 シェルコマンドが格納されているファイルとみなされ、 それを読み込むためサブシェル (すなわち、 別のプロセス) が生成されます。 かっこで囲んだコマンドもまた、 サブシェルで実行されます。

特殊コマンド
以下のコマンドはシェルプロセス内で実行され、 特に記されない限り、 そのコマンドに対する入力/出力のリダイレクト指定は許されません。

# 会話型でないシェルでは、 # に続くものはすべてコメントとみなされます。 つまり、 その行の # 以降は無視されます。 会話型シェルでは # は特に意味を持ちません。

: このコマンドは何もしません。 0 の終了コードが返ります。

. file file からコマンドを読み込んで 実行し、 復帰改行します。 $PATH で指定されるサーチパスは file を探すためのディレクトリとして使われます。

break [n]
for または while コマンドがあれば、 そのループから抜け出します。 n が指定されると、 指定の n レベルから抜け出します。

continue [n]
for または while ループの次の反復を再び始めます。 n が指定されると n 番目のループから再開します。

cd [arg]
現行ディレクトリを指定 arg に変えます。 シェルパラメータ $HOME の値がデフォルトです。

eval [arg ...]
arg... はシェルの入力として読み込まれ、 シェル変数の評価などが行われ、 その結果のコマンドが実行されます。

exec [arg ...]
新プロセスを生成せず、 シェルに代わって arg で指定のコマンドが実行されます。 入出力引数を指定してもよく、 他に引数が与えられなければ、 シェルの入出力が変更されます。

exit [n]
n で指定された終了ステータスで会話型でないシェルを終了させます。 n が省略されると、 終了ステータスは最後に実行されたコマンドの終了ステータスと 同じになります(EOFもシェルを終了させます)。

export [name ...]
指定の name が、 引き続き実行されるコマンドの 環境 に引き継がれるようにします。 引数がないと、 その export できる name のリストが表示されます。 関数は export できません。

login [arg ...]
’exec login arg ...’ と等価です。

read name... 
標準入力から 1行読み込み、 その入力の word 列が変数 name に順番に代入されます。 name 残った word は、 最後の変数に代入されます。 EOF が入力されない限り、 リターンコードは 0 です。

readonly [name ...]
指定の name は、 リードオンリー(読み込み専用)となり、 これらの name の値は、代入によって変更できなくなります。 引数がないと、 すべてのリードオンリー name のリストが表示されます。

set [−eknptuvx [arg ...]]

−e 会話型モードでないとき、 コマンドが正常終了しないと即座に終了します。

−k すべてのキーワード引数は、 コマンド名より先に置かれたものに限らず、 コマンドに対する環境に置かれます。

−n コマンドの読み込みを行いますが、 それらを実行しません。

−t コマンドを 1個読み込みそれを実行して終了します。

−u 置換の際、未設定変数をエラーとして扱います。

−v シェルの入力行を読み込むごとにそれを表示します。

−x コマンドとその引数を実行時に表示します。

− -x オプションと −v オプションの働きを止めます。 これらのフラグはまたシェルの起動にも使われます。 現行のフラグセットは $− で見ることができます。 残りの引数は、 位置パラメータで、 $1、 $2...  の順に代入されます。 引数がないと、 全 name の値が表示されます。

shift $2、 $3...  の位置パラメータが、 $1、$2...  に名称変更されます。

times
シェルから実行されたプロセスのユーザおよびシステムの積算時間を表示します。

trap [arg] [n] ...
arg はシェルがシグナル n を受け取ったとき読み込まれ 実行されるコマンドです。 (arg はトラップがセットされた時と、 トラップが取り込まれた時にスキャンされる点に注意してください。) trap コマンドはシグナル番号の順に実行されます。 arg がないと、 シグナル番号 n のすべてのトラップは、 元の値にリセットされます。 もし arg が ナル文字列だと、 このシグナルはシェルおよびそれが起動するコマンドから無視されます。 もし n (シグナル番号) が 0 だと、 コマンド arg はシェルから抜け出る時実行されます。 引数のまったくない trap コマンドは、 それぞれのシグナル番号に対応するコマンドのリストを表示します。

umask [ nnn ]
ユーザのファイル生成マスクが 8進数 nnn にセットされます (umask(2) を参照)。 nnn が省略されるとカレントマスク値が表示されます。

wait [n]
指定のプロセスを待ち、 その終了ステータスを報告します。 n が与えられないと、 すべての現在実行中の子プロセスの終了を待ちます。 このコマンドからのリターンコードは常に待っていたプロセスのものです。

起動
引数 0 の最初の文字が − だったら、 コマンドは $HOME/.profile から読み込まれ、 実行されます。 ただし、 そのようなファイルがある場合にかぎります。 それからコマンドは次のように読み込まれます。 以下のフラグはシェルが起動されたとき、そのシェルによって解釈されます。

−c string −c フラグがあるとコマンドは string から読み込まれます。

−s −s フラグがあるかまたは引数なしでシェルを起動すると、 コマンドは標準入力から読み込まれます。 −s の後の引数は位置パラメータとなります。 シェルの出力は記述子 2 に出力されます。

−i フラグ −i があるかまたはシェルの入力および出力が端末に接続されていると (gtty 参照)、 このシェルは会話型となります。 この場合、 ターミネートシグナル SIGTERM (sigvec(2) 参照) は無視されます。 (したがって、‘kill 0’ は、 会話型シェルを終了させません) 。 割り込みシグナル (SIGINIT) は受け付けられますが、 無視されます。 (したがって、 wait は割り込み可能です。) どんな場合でもシェルは SIGQUIT を無視します。 このほかの引数とフラグは set コマンドで述べられています。

多国語対応

漢字をはじめ多国語の入力に対応するための処理は、以下のとおりです。

tty モードを sjis、 euc、 jis または、 tca (台湾コード) モードに設定することで、 ASCII文字と同様に漢字を入力することができます。 ‘"’、‘&’、‘|’、‘;’、‘<’、‘>’、‘(’、‘)’などのメタキャラクタは ASCII文字でなければなりません。 全角文字の ‘”’ や ‘&’ などは通常の文字と同じ扱いになります。 同様に全角スペース(シフトJISコードなら 0x8140、EUC なら 0xa1a1)は 引数のセパレータとしては使用できません。

ファイル名操作用のメタキャラクタである ‘∗’、‘?’、‘[...]’ などに対して、 2バイトコードは 1文字として扱われます。

シェル変数や環境変数の値にも2バイトコードが使用できます。
 

関連ファイル

$HOME/.profile
/tmp/sh∗
/dev/null

関連コマンド

csh(1), test(1), execve(2), environ(7)

診断

構文エラーのようなシェルによって検出されるエラーが見つかると シェルは 0 以外の終了ステータスを返します。 シェルが会話型で使われていない場合は、 シェルファイルの実行は放棄されます。 そうでなければ、 シェルは最後に実行されたコマンドのステータスを返します (exit 参照) 。

バグ

& で起動する非同期プロセスの標準入力を << を使って変えると、 シェルはどの入力ファイルから入力するかわからず混乱します。 その結果、 ゴミファイル /tmp/sh∗ が作成され、 シェルは別の名前でそのファイルを見つけられないというエラーを出力します。

備考

setuid / setgid のシェルスクリプトについて
NEWS-OS Release 4.0 より、セキュリティ上の問題から setuid または setgid されたシェルスクリプトを実行する際、 コマンドのサーチパスを以下のように変更します。
 

シェル設定されるサーチパス
/bin/csh(/usr/ucb /bin /usr/bin /usr/sony/bin)
/bin/sh/bin:/usr/bin:/usr/sony/bin

 
必要に応じてシェルスクリプト中でサーチパスを再設定してください。
 
setuid されたアプリケーションプログラムから system() 関数や popen() 関数を使用する場合も、同様です。 これらの場合は、コマンドはフルパスで指定するようにしてください。

NEWS-OSRelease 4.1C

Typewritten Software • bear@typewritten.org • Edmonds, WA 98026