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

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

Kornシェルの基本的な仕組み

ここまでで、スクリプトヘッダーと変数の定義方法を学び、Kornシェルスクリプトをどのように書き始めればいいのかを学んできました。それではKornシェルコードを書き始める時間です。

ファイルから数行を読み込む処理から始めてみましょう。このケースでは、すでに変数に定義されている/etc/passwdファイルを使い、ユーザー名のみを表示させます。

Listing 4: forループ

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

#変数定義
HOME="/home/jthomas" #ホームディレクトリー
DATE=$(date) # DATEにシェルコマンドのdateの出力結果と同じものを代入する
HOSTNAME=$(hostname) # HOSTNAMEにhostnameコマンドの出力結果と同じものを代入する
PASSWORD_FILE="/etc/passwd" # AIXパスワードファイルパスを設定

#始めのコード

for username in $(cat $PASSWORD_FILE | cut -f1 -d:)
do

       print $username

done

この構文はforループと呼ばれています。これを使うことで、/etc/passwdファイルを開き、1回に1行ずつ読み取りを行い、ファイルの最初のフィールドを切り出し、その行を表示します。「|」という特殊文字に注目して下さい。これはパイプと呼ばれています。パイプを使うことで、あるコマンドの出力を別のコマンドにリダイレクトさせることが出来ます。

保存したスクリプトを実行すると、Listing 5のような結果が表示されます。

Listing 5: スクリプトを実行する

$./my_first_script.ksh
root
daemon
bin
sys
adm
uucp
nobody
lpd

スクリプトは出力結果をスクリーンに表示しました。別の方法として、以下のようにすれば出力をファイルに書き出すことも出来ます。

print $username >> /tmp/usernames

「>>」はprintコマンドに対して、ファイルにユーザー名を順番に追記するようにさせる際に使用します。こうすることで、これ以降はターミナル上でテキストは表示されなくなります。スクリーンとファイルの両方に出力させたい場合は、以下のコマンドを使用します。

print $username | tee -a /tmp/usernames

teeコマンドは出力をターミナルとファイルの両方に対して同時にリダイレクトさせてくれます。

ここまでで、forループを使ってファイルから読み込みを行い、ユーザー名のみを切り出し、ファイルまたはターミナルへリダイレクトする方法を学びました。

エラーのチェック

もし、/etc/passwdファイルが存在しなかった場合、何が起こるでしょうか?スクリプトがこけるというのが答えです。Listing 6はファイルが存在するかをチェックする構文です。

Listing 6: ファイルが存在するか確認する構文

#始めのコード
if [[ -e $PASSWORD_FILE ]]; then #ファイルが存在するか確認し、存在すれば処理を続ける

     for username in $(cat $PASSWORD_FILE | cut -f1 -d:)
     do

         print $username

     done
else

         print "$PASSWORD_FILE が存在しませんでした。"
         exit
fi

このコードは条件付きif文と言います。/etc/passwdファイルが存在すれば、スクリプトは処理を続行します。ファイルが存在しなければ、ターミナルに「/etc/passwd が存在しませんでした。」と表示して、処理を抜けます。条件付きif文は、ifから始まり、文字を逆さにした「fi」で閉じられます。

$?とは

AIXでコマンドを実行するたびに、システムはある変数を設定しています。これは$?で参照することが出来ます。AIXは成功時に「0(ゼロ)」を、失敗時にゼロ以外の数字をこの変数に設定します。これはKornシェルスクリプト作成の際に非常に重要な点です。Listing 7は、有効または無効なAIXコマンドを実行した際にどのように$?が設定されているかを表示したものです。

Listing 7: 有効または無効なAIXコマンドで$?がどのように設定されるか

$date
2008年 5月 10日 土曜日 0時 2分 31秒 EDT
$echo $?
0
$uptime
12:02AM   up 259 days,  10:47,  5 users,  load average: 4.71, 10.44, 12.62
$echo $?
0
$IBM
ksh: IBM:  not found.
$echo $?
127
$aix
ksh: aix:  not found.
$echo $?
127
$ls -l /etc/password
ls: 0653-341 The file /etc/password does not exist.
$echo $?
2

これはKornシェルを作成する際に非常に役立ちます。なぜなら、エラーをチェックする別の方法になり得るからです。以下で、/etc/passwdファイルが存在するか確認する別の方法を紹介します。

#始めのコード
PASSWORD_FILE="/etc/passwd"

ls -l $PASSWORD_FILE > /dev/null 2>&1

このコマンドはファイルをリスト表示します。しかし、ファイルが存在するか否かを気にする必要はありません。重要なのは、このコマンドのリターンコードを取得できたということです。ちなみに、大なり記号「>」を使うことで、コマンドの出力をリダイレクトさせることが可能です。出力のリダイレクトに関しては、後ほどもう少し学びましょう。

Listing 8は$?の使い方を説明したものです。

Listing 8: スクリプトで$?を使う

#始めのコード
PASSWORD_FILE="/etc/passwd"

ls --l $PASSWORD_FILE > /dev/null 2>&1
if [[ $? != 0 ]]; then

       print "$PASSWORD_FILE は存在しませんでした。"
       exit

else

   for username in $(cat $PASSWORD_FILE | cut -f1 -d:)
   do

       print $username

   done
fi

ファイルの存在確認を直接行う代わりに、ファイルのリスト表示をしようとしました。ファイルのリスト表示が出来れば、ファイルは存在します。ファイルのリスト表示が出来なければ、ファイルは存在しません。AIXでは、「ls -l ファイル名」コマンドでファイルのリスト表示が出来ます。このAIXコマンドが成功したかどうかは、$?変数を確認することで判定することが出来ます。

【訳注】 「Kornシェルスクリプト入門 Part 3」に続きます。