※このエントリーは、developerWorks : AIX and UNIXの「Korn shell scripting」を翻訳したエントリーのPart 3です。

【訳注】 「Kornシェルスクリプト入門 Part 2」の続きのエントリーです。

標準入力、標準出力、標準エラー

これらを理解するのは必須です。基本的に入出力には3つの出力元が存在します。AIXでは、STDIN、STDOUT、STDERRと呼ばれています。STDINは、キーボードを通じてあなたが入力した内容を参照します。STDOUTはコマンドが実行された時にスクリーンに表示される出力のことです。STDERRはコマンドが失敗した時にスクリーンに表示されます。STDINとSTDOUTとSTDERRファイルディスクリプターはそれぞれ、1、2、3という番号にマッピングされています。

コマンドの実行結果が成功か失敗かを確認したい場合は、Listing 9のようなやりかたをします。

Listing 9: STDOUTとSTDERRの出力をリダイレクトする

$date /dev/null 2>&1  # このコマンドのすべての出力を見られないようにする

if [[ $? = 0 ]]; then
      print "date コマンドは成功しました"
else
      print "date コマンドは失敗しました"
fi

このコードでは、AIXのdateコマンドを実行しています。STDOUT(ファイルディスクリプター1)またはSTDERR(ファイルディスクリプター2)の出力は見られないようにすることが出来ます。続いて、条件付きif文でこのコマンドのリターンコードを確認しています。以前に学んだように、コマンドが「0(ゼロ)」を返せば、成功です。ゼロ以外では失敗となります。

関数

Kornシェルスクリプトでは、functionという言葉は予約語になっています。関数はスクリプトをセグメントに分割するための手法の一つです。これらのセグメントは、関数をコールした時のみ実行されます。これまで作ってきたコードにエラーチェックの関数を作成しましょう。Listing 10をご覧下さい。

Listing 10: エラーチェック関数

##################
関数 if_error
##################
{
if [[ $? -ne 0 ]]; then # 関数に渡されたリターンコードをチェックする
    print "$1" # リターンコードがゼロより大きい場合にはエラーメッセージを出力し、処理を抜ける
exit $?
fi
}

もし、スクリプト内で単純にコマンド実行させたいと考えたならば、上記のように$?でエラーチェックするようなコードを簡単に作成することが出来ます。処理が失敗したかを確認したい場合は、その度にif_error関数を呼び出すだけで済みます。Listing 11をご覧下さい。

Listing 11: if_error関数をコールする

rm -rf /tmp/file #ファイルの削除
if_error "エラー: /tmp/file の削除に失敗しました"

mkdir /tmp/test #ディレクトリー作成
if_error "エラー: /tmp/testの作成に失敗しました"

上記のコマンドを実行する度に、if_error関数がコールされます。エラーチェックの際に特定のメッセージを表示させたい場合は、if_error関数にメッセージを渡すことも出来ます。これが優れている点は、一度シェルコードを書いてしまえば、何度も何度も同じエラーチェック機能を使いまわし出来る点です。こうすればシェルスクリプトの作成は早くかつ簡単になります。

case文

case文は、if文を使っていた場所に使うことが出来る別の条件判定文です。case文は、caseという文字で始まり、文字を逆さまにした「esac」という文字で閉じられます。case文を使えば、スクリプトを発展させ、他のタスクを実行させる際などに素早く開発することが出来ます。Listing 12はcase文の仕組みの例です。

Listing 12: case文

case 値 in
"パターン1")
 値が「パターン1」と合致した際に実行されるコマンド
 ;;
esac

それでは、同じ日の異なる時間にファイルを削除したいとします。現在時刻をチェックするための変数はこのように設定できます。

TIME=$(date +%H%M)

Listing 13で紹介しているコードは、午後10時と午後11時にファイルを削除してくれます。そのため、該当時間帯にこのコードが実行されると、$TIMEの現在時刻とcase文の時間が合致しているかを確認します。そして、時間が合致していればコードは実行されます。

Listing 13: 時間をチェックするcase文

case $TIME in
                 "2200") #午後10:00の意味
                  rm -rf /tmp/file1
                        ;;
                  "2300")#午後11:00の意味
                  rm -rf /tmp/file1
                        ;;
                    "*")
                        echo "何もしない" > /dev/null
                        ;;

esac

すべてのスクリプトを一つに

これまであなたが作ってきたスクリプトヘッダーと変数と式を組み合わせて、Listing 14のものを作ってみましょう。

Listing 14: Kornシェルスクリプトの例

$vi my_second_script.ksh
#!/bin/ksh
###################################################
# 作者: Jason Thomas
# 目的: ユーザーに初めてのスクリプトの作成方法を見せるためのスクリプト
# 2008年5月1日
###################################################

#変数定義
HOME="/home/jthomas" #ホームディレクトリー
TIME=$(date +%H%M) # DATEにシェルコマンドのdateの出力結果と同じものを代入
HOSTNAME=$(hostname) # HOSTNAMEにhostnameコマンドの出力結果と同じものを代入する

##################
関数 if_error
##################
{
if [[ $? -ne 0 ]]; then # 式に渡されたリターンコードをチェックする
    print "$1" # リターンコードが0以外ならば、エラーメッセージを表示して処理を抜ける
exit $?
fi
}

if [[ -e /tmp/file ]]; then  #ファイルが存在するか最初に確認する
   rm -rf /tmp/file #ファイルを削除する
   if_error "エラー: /tmp/fileの削除に失敗しました。"
else
   print "/tmp/fileは存在しません。"
fi

if [[ -e /tmp/test ]]; then
     mkdir /tmp/test #testディレクトリを作成する
     if_error "エラー: /tmp/testディレクトリの作成に失敗しました。"
else
     print "ディレクトリがすでに存在します。ディレクトリを作成する必要はありません。"
fi

case $TIME in
                 "2200")
                  rm -rf /tmp/file1
                        ;;
                  "2300")
                  rm -rf /tmp/file1
                        ;;
#スクリプト終了
esac

スクリプトを実行するには、単純に「./スクリプト名.ksh」とタイプするだけです。

$./my_second_script.ksh

コマンドラインからの入力内容をスクリプトに渡す

コマンドライン上であなたが入力した内容をスクリプトが受け取るようにすることが出来ます。Listing 15をご覧下さい。

Listing 15: スクリプトに入力内容を渡す

$vi scriptname.ksh
#!/bin/ksh

OPTION=$1

print "I love $OPTION"

$./scriptname.ksh milk
I love milk
$./scriptname.ksh tea
I love tea
$./scriptname.ksh "peanut butter"
I love peanut butter

スクリプトに値を引き渡す時、スクリプト名の後ろの最初のオプションは$1と呼ばれます。同じく2つ目以降のオプションは$2、$3と続きます。これを知っていれば、スイッチやオプションを持つUNIXコマンドと同じようにスクリプトを作成することが出来ます。

スクリプトからEメールを送る

スクリプトでいくつかの種類のレポートを作成するようにすることが出来ます。例えば、システムに新しいユーザーが登録されたかどうかを毎日トラッキングするスクリプトがあります。このスクリプトはファイルに結果を出力し、それをあなた自身に送信します。こうすることで、あなたは毎日、システムに追加された全ての新ユーザー情報のコピーを受け取ることが出来ます。これを実現するには、以下のようなコマンドを実行します。

$REPORT="/tmp/users"

cat $REPORT | mailx -s "User admin report from server XYZ" Jason_Thomas@kitzune

これにより、$REPORTファイルのコンテンツがEメールであなたに送られます。「-s」はEメールの件名を表しています。これはとても使い勝手のいいスクリプトです。

最後に

Kornシェルスクリプトを作成すれば、多くの無駄な時間が省かれ、あなたの仕事はより簡単になると思います。最初は躊躇するかもしれませんが、簡単なものから始め、一行一行積み重ねていくことです。いつでもこのステップは忘れないで下さい。スクリプトヘッダーを作成し、変数を定義し、作品のエラーチェックを行う。いつか、あなたは自分がやっている全てのことをスクリプトで書こうとしているかもしれません。

入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界 入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界
ブルース ブリン Bruce Blinn

ソフトバンククリエイティブ 2003-02
おすすめ平均

Amazonで詳しく見る by G-Tools