計算機科学概論 Bourneシェル(sh) コマンドの実行 変数置換 コマンド

Bourneシェル(sh)
計算機科学概論
第4回
Bourneシェル
• 対話的シェルのときにやったCシェルとは別系統
のシェル
‒ 次回やるシェルスクリプトには通常こちらを使う
‒ 同系統の後継: ksh, bash, zsh
• 起動
% sh
• 終了
$ exit
コマンドの実行
変数置換
• コマンドの起動・リダイレクション・パイプはC
シェルとほぼ同様
• 主な違い
• 「$変数名」や「${変数名}」がその変数
の値で置き換わる
‒ ジョブ制御やヒストリ置換はない(かもしれない)
‒ 「~」はホームディレクトリの絶対パス名に展開さ
れない(かもしれない)
• 「$HOME」を用いる
$ 環境変数=値 … コマンド名 引数 …
‒ 環境変数の値を一時的に変えてコマンドを実行
$ PAGER=cat man ls
コマンド置換
• 「`コマンド`」がコマンドの出力結果で置き換
わる
‒ 出力結果の末尾の連続する改行は取り除かれる
$ expr 2 + 3
$ echo 2 + 3 = `expr 2 + 3`
• shの扱うデータは文字列のみ
‒ 数値を扱うとき(数値演算・比較)は、外部コマンド
の力を借りなければならない
• 変数への代入 …「変数名=値」
‒「=」の周辺に空白を入れてはならない
$ foo=FOO; foobar=FOOBAR
$ echo $foobar ${foo}bar
• 変数を環境変数として扱いたいときは
「$ export 変数名」
終了ステータス
• コマンドが正常に終了したかどうかを表す値
‒ 0が正常終了、0以外が異常終了
‒ コマンドによっては0が真、0以外が偽
• 「$?」は最後に実行した(バックグラウンドでな
い)コマンドの終了ステータスに置換される
$ test 2 -lt 3; echo $?
$ [ 2 -gt 3 ]; echo $?
「[」はコマンド名、「]」は引数の一つなので、
そう解釈されるように適宜空白を入れる
終了ステータス
• コマンド1 && コマンド2
‒ コマンド1が正常終了したとき(真のとき)に限り、コ
マンド2を実行
$ foo=2; bar=3
$ test $foo -lt $bar && echo "$foo <
$bar"
• コマンド1 || コマンド2
‒ コマンド1が異常終了したとき(偽のとき)に限り、コ
マンド2を実行
$ [ $foo -gt $bar ] || echo "not \c";
echo "$foo > $bar"
省略可
for
1個以上の改行
1個以上の改行
で置き換え可
• for NAME [in WORDS]; do COMMANDS;
done
制御構造
• 計算の流れを変えるもの
‒for: 与えられた語の列に関する繰り返し
‒while, until: 条件による繰り返し
‒if: 条件による分岐
‒case: パターンマッチによる分岐
コマンドの終了ステータス
が0(真)か0以外(偽)か
while, until
• while TEST-CMDS; do CONSEQUENT-CMDS; done
– TEST-CMDS を実行し、最後のコマンドの終了ス
テータスが0(真)である間、 CONSEQUENT-CMDSを
実行
$ for f in apples bananas cherries
> do
> echo "I like $f."
> done
• until TEST-CMDS; do CONSEQUENT-CMDS; done
if
case
• 複数のものが指定できる部分の後には
「;」が来る
• if TEST-CMDS; then
CONSEQUENT-CMDS;
[elif MORE-TEST-CMDS; then
MORE-CONSEQUENTS;] ...
[else ALTERNATE-CONSEQUENTS;] fi
$ x=100; y=24
$ if [ $x -gt $y ]; then w=$x; x=$y; y=
$w; fi
$ while [ $x -ne 0 ]; do
> w=`expr $y % $x`; y=$x; x=$w
> done
$ echo $y
‒ 「終了ステータスが0以外(偽)である間」となる以外
は while と同じ
• case WORD in [PATTERN [| PATTERN]...)
COMMANDS ;;]... esac
– WORDがマッチする最初のPATTERNに対応する
COMMANDSを実行
$ month=10; year=2004
$ case $month in
> 2)! !
!
省略(次頁) ;;
> [469]|11)!
> [13578]|1[02])
> esac
$ echo $ndays
ndays=30 ;;
ndays=31 ;;
case
• 前頁の省略部分
case `expr $year % 4`,`expr $year %
100`,`expr $year % 400` in
0,0,0) ndays=29 ;;
0,0,*) ndays=28 ;;
0,*)
ndays=29 ;;
*)
ndays=28 ;;
esac
• shにはレコードが無いので、文字列の連結とパ
ターンマッチで代用
ブランクの解釈・
ファイル名の生成
$ foo="a
b *"
$ echo $foo
$ echo "$foo"
$ echo `ls`
$ echo "`ls`"
• iTunes2インストーラによるデータ削除の事例
– 旧バージョン削除部分における「"…"」の付け忘れ
– 特定条件下でのみ発現
変数/コマンド置換とブランク
の解釈・ファイル名の生成
• 変数置換($変数名)とコマンド置換(`コマ
ンド`)においては、それぞれの置換の後
に以下の作業が行われる
‒空白や改行(ブランク)による語への分割
‒「*」や「?」や「[…]」によるファイル名の
生成
• ただし「"…"」の内部では行われない