よくあるプログラミングの入門段階でやるような、 「1から10までの数を順々に各行に印字するプログラム」を シェルで実現してみる。
いま使っているシェル(コマンドインタプリタ)は、 以下のように確認できる。
ps
というコマンドで、ps以外にもう1つ bash というプロセス名が表示される。
これが今使っているシェルの名前である。
Unixの初期の頃に、sh という標準シェル (Bourne氏が作ったもので、B-シェル、 Bourneシェルなどとも呼ばれた) が使われていて、
その後、いくつかの変遷があって、 B-シェルを進化させたものが作られ、 Bash(Bourne Again SHell ; 「生まれ変わった」と掛け言葉になっている)と呼ばれている。 (というシェルの系譜については前回述べた。)
最近になってからの機能拡張の結果、 今では必ずしもなり立たなくなった解説事項や、 今ではもっと簡便に実現できるという実現例も、 本講座での解説では含まれることがありますが、
本講座を通じてUnixが元来持つ考え方を 理解してもらうのが目的なので あえて古い話も残してあります。
念のため、古い話になってしまっているかも知れない事項には (※)印をつけておきます。
n=1 --1
while [ $n -le 10 ] ; do --2
echo $n --3
n=`expr $n + 1` --4
done --5
while による制御構造は Bashのマニュアル (「while」でページ内検索してみて下さい)には、
while list-1; do list-2; done
とある。
ここで、list-1, list-2 は、コマンドのことと考えていい。
複数のコマンドを順々に実行(逐次実行)するために、
意味は同じ。
ここで list-1, list-2 という書き方がされているのは、
縦並べ横並べを問わず、コマンド(やパイプライン)を
逐次実行処理したもの、というような意味になる。
前述のプログラム例(改行で区切った)を、セミコロン区切りで 一行で書くこともできる。
n=1 ; while [ $n -le 10 ] ; do echo $n ; n=`expr $n + 1` ; done
n はシェルで使われる「変数」
変数は、名前と値を持つ
変数にセットされる値は、文字列だけ (※)
(通常のプログラミング言語のように数値やその他のデータは扱わない)
代入の際は、= の両側を空けない (空白を入れると n というコマンドに = と 1 というパラメータを付加して 呼び出したとみなされる)。
set コマンドで、変数の設定状況がすべて表示される
が、昨今のUnixではデフォルトで設定されているものが 多すぎて見つけ出すのに苦労する。
以下の2つの方法が使えるだろう。
echo $n
# または
set | grep 'n='
変数を参照するときは 変数名の前に $ を付加する。
後者の例では grepコマンドが 標準入力として与えられたデータ
(すなわち set コマンドの出力)から、 n= という並びを含む行を
選び出して表示する。
パラメータとして、数式を渡すと、 その式を計算した結果を (標準出力に)出力する。
数式は、数値と演算子に分けて(スペースで区切って)与える必要がある。
使用例:
expr 1 + 2 + 3
# => 6
expr $n + 1
# 変数n に設定した値が展開されてからexprに渡され、
# それに1を加えた値が印字される
expr コマンドの結果は、標準出力に書き出される。 これをシェルで 活用するための仕組みとして 「コマンド置換」がある。
前々節の例で、変数名に$を前置したものが、
(コマンド実行に先立って)その変数の値に置き換えられた、
それと同様に、
(バッククォート)で囲まれた部分が、
たとえば n=1 のあと、以下のコマンドが入力されたとき
n=`expr $n + 1`
…
のあった場所がそのまま 結果の文字列 2
に置き換えられなお、古くから使われている方の `` で挟む書き方の コマンド置換は、 コマンド置換の対象の中でコマンド置換、 という入れ子構造を作るときにややこしいことになる。
while構文の (マニュアルの表記で) List-1 は、繰り返しの条件判定 を行うためのコマンドを書く場所。
ここでよく使われるのが test コマンド。
テスト(条件判定)すべき条件をパラメータで渡して使う。
ファイルに関するテスト、文字列に関するテスト、 数値に関するテストなど 様々な用途がある。
大小比較のための演算子として、普通の数学では < > ≧ ≦ などの 記号が用いられるが、> < = などの文字は、シェルでは代入や リダイレクトの記号として使われている。
testコマンドには、[ (左ブラケット)という別名がある。
機能がは完全にtestコマンドと同じだが、パラメータとして最後に ] (右ブラケット)を追加することが求められることだけが違う。
その結果、
while [ $n -le 10 ] ; do
というような記法が有効になる。 終了ステータス
test コマンドは、検査結果を終了ステータスという形でシェルに通知する。
while
、 if
、
&&
、 ||
、
といった制御構造でシェルが内部的に使用する。?
(参照するときは $?
)
にもその値がセットされる。以下のようなコマンドを試してみて下さい
test 1 -le 2
echo $?
test 1 -gt 2
echo $?
[ 1 -le 2 ]
echo $?