UNIXシェルスクリプト第10章 Part2
2つのディレクトリを比較するシェルスクリプト DirCmp
※指定した2つのディレクトリ下にあるファイル構成を比較し、
等しくないファイルをリスト表示する。以下の3パターンの表示を行う。
1番目のディレクトリ下にあって、2番目のディレクトリ下にはないファイル。
2番目のディレクトリ下にあって、1番目のディレクトリ下にはないファイル。
両方のディレクトリにはあっても、名前が同じだけで実体が異なるファイル。
-v 詳細表示オプション
2つのディレクトリ下に同じ名称のファイルがあってその中身が異なっているとき、
ファイルの何行目がどのように違っているのかを表示する。
DIR1_FILES=/tmp/files1.$$
$$にはスクリプトを実行した時のプロセスIDが入る。
そのため別の人が同時に複数動作させても利用する一時ファイルはそれごとに異なって混乱することはない。一時ファイルを利用する場合にはこのように$$変数を使うのはいいこと。
正常終了時も、途中終了時もこれらの一時ファイルを削除するようにしないといけない。
trp `rm -f /tmp/*.$$; exit 1` 1 2 3 15
このシェルスクリプトは実行中には1,2,3,15番のシグナルしか受け付けない。
つまりハングアップ、割り込み、クイット、終了。
これらのシグナルを受け取って処理が途中で中断された場合には、trapコマンドの引数が実行される。
find . \( -type f -o -type l \) -print | sort > $DIR1_FILES
カレントディレクトリ内で、ファイルタイプが f または l のファイルを探して、一覧表示する。ファイルタイプ l はシンボリックリンクを表す。
findコマンドがタイプ指定の部分を解釈しなくてはならないので、丸括弧を使い、\でエスケープしている。
sortコマンドでソートし、その結果を$DIR1_FILESに書き込む。
cat $DIR1_FILES $DIR2_FILES | sort | uniq -d > $COMMON_FILES
uniqコマンドは重複した行を1行にして表示する。
-dオプションは重複した行だけを表示する。
-uオプションは重複していない行だけを表示する。
なお、uniqコマンドは前後に並んだ行を比べるだけなので、先にsortコマンドで並べ替えておく必要がある。
if [ -s $TMP ] ; then
-sオプションはファイルが存在し、かつサイズが0でなければ真。
cmp -s $DIR1/$f $DIR2/$f
cmpコマンドは内容を比較する。
cmpコマンドの終了コードはファイルの内容が異なっていれば1になり、一致していれば0になる。
diff $DIR1/$f $DIR2/$f
diffコマンドでファイルの内容の違いを出力する。
UNIXシェルスクリプト第10章 Part1
ファイルの連結、表示を行うシェルスクリプト Cat
#!/bin/sh
シェルスクリプトの最初にはこの宣言が必要。
/bin/shで動作させるため。
if [ ! -r "$1" ] ; then
-rオプションはファイルが存在し、読み込み可能かどうかを判定する。
IFS=
while read LINE
readはIFS変数にセットされている空白、タブ、改行などを区切り文字として使う。
IFS変数にはデフォルトで空白、タブ、改行がセットされている。
IFS変数を空にすることで何も無視する文字はないとreadコマンドに教えることができる。
※実際には現在の値を別の変数に代入しておいて、後で元に戻すのが賢明。
while read LINE
do
処理
done <"$1"
whileとreadを使ってリダイレクトしてファイルを読みこませると、
ファイルの終わりの行までを1行ずつ順番に処理させることができる。
shift
スクリプトの引数($1以降)の位置を1つずらす。
exit $ERROR
$ERRORの値が終了コードになる。
UNIXシェルスクリプト第9章 Part9
応答要求メッセージを出力する関数 Prompt.sh
echo "${@-> }\c"
echo -n "${@-> }"
${@-> } という部分は $@ と ${variable:-value} , ${variable-value} の組み合わせ。
応答要求のスタイルを定型化した関数 Question.sh
if [ $# -lt 3 ] ; then
-lt は Less than ( < ) と同じ意味。
+x | -x ) set $ANSWER ;;
シェルはsetコマンドでオプションを切り替えられる。
-xオプションは「実行された内容を変数などを置換した状態で表示する」ためのもの。
つまりこれ以後、デバッグモードとしてシェルスクリプトが動作する。
+xを入力するとデバッグモードをオフにする。
!* ) eval `expr "$ANSWER" : "!\(.*\)'`
expr string : regex はマッチする文字列を返し、マッチしなかった場合は0を返す。
正規表現の一部が \( と )\ の間に囲まれる場合、その囲まれる文字列を返し、
マッチしなければヌル文字列を返す。
evalコマンドは変数や特殊文字の変換処理を行ってからコマンドとして実行する。
UNIXシェルスクリプト第9章 Part8
システムのタイプが正しいかどうかを判定する関数 IsSystemType.sh
※unameコマンドを使ってシステムの名前を取得する。
uname -s OSの名称
uname -m ハードウェアのタイプ
uname -r OSのリリース番号
if [ "$1" = "`uname -s`" ] ; then
return 0
elif [ "$1" = "`uname -m`" ] ; then
return 0
else
case `uname -r` in
"$1"* ) return 0 ;;
esac
fi
OSの名称、ハードウェアのタイプ、OSのリリース番号の順にチェック。
リリース番号については厳密に一致しなくても正しいものとするための処理を行っている。
UNIXシェルスクリプト第9章 Part7
文字列が数値化どうかを判定する関数 IsNumeric.sh
※シェル変数に代入されている値は、たとえ数値であれ文字として扱われる。
しかしexprコマンドなどは。その文字列を数値として計算させることができる。
expr "$1" + 1 > /dev/null 2>&1
実行終了ステータスが欲しいので1を足して、結果やエラーを捨て去る。
exprコマンドの実行終了ステータスについて
結果が0になるときの終了ステータスは1
結果が0以外になるときの終了ステータスは0
計算できなかった時の終了ステータスは2
if [ $? -ge 2 ] ; then
-ge は >= と同じ意味。
$? には直前のコマンドの実行終了コードが代入される。