next up previous contents
Next: シェルスクリプトの使い方 Up: シェルスクリプトを書く Previous: シェルスクリプトを書く

シェルスクリプトの文法

まずコメントは#で始まり、行末までです。普通にcshからスクリプトを呼び出 すときはなくてもよいのですが、第一行目はそのシェルスクリプトをどのシェ ルを使って実行するかを教えるために使う場合があります。例えばUNIXの標準 シェルであるshを使うアプリケーションがcshで書かれたスクリプトを実行す る場合、そのままではshのコマンドと解釈するためシンタックスエラーになり ます。しかし第一行目に次のように書いておけばshがcs hを呼び出してスクリ プトを実行するため正常に働きます。

        #! /bin/csh

UNIXの場合色々なシェルが使われるために導入された工夫です。誰から呼び出 されるかわからない汎用的なスクリプトはこれに従うべきです。他人に見せる ときもcshで書いてあるのだということが一目瞭然です。個人で使う分には必 要ないでしょう。

スクリプトにおいても変数を使います。すでにシェル変数や環境変数について は説明しました。参照は両方とも同じ$を使います。変数名の区切りを明確に するためには変数名をでくくります。シェル変数と環境変数は文法上は区別 がつきませんので通常シェル変数は小文字の、環境変数は大文字の名前を付け ます。変数の定義の仕方はこの二つで違います。

        # シェル変数の定義
        set testvar = test
        # 環境変数の定義
        setenv TESTVAR test

スクリプトの中で制御のために使う変数はシェル変数を使うべきです。環境変 数はシェルが呼び出したプロセスに渡されますが、シェル変数は渡されません。 シェルスクリプトからさらにシェルスクリプトを呼び出すときには環境変数を 使う必要があります。シェル変数に値を与える方法にはもう一つ setは右辺の文字列が文字列として代入されるのに対して、 て評価されその結果が代入されます。次をやってみてください。

        % set testcount = 1
        % echo $testcount
        1
        % set testcount = ( $testcount + 1 )
        % echo $testcount
        1 + 1
        % @ testcount = $testcount + 1
        % echo $testcount
        3
        %

setでは+ 1が文字列としてそのまま変数に代入されているのに対し、(その意 味では+は文字であって演算子ではありません。) れその演算結果が代入されています。

式の値の評価は繰り返しや条件分岐に使われます。繰り返しはwhileです。

        # whileを使う
        @ testcount = 0
        while( $testcount < 10 )
            echo $testcount
            @ testcount = $testcount + 2
        end

これを実行すると端末に0から8まで2おきに数字を表示します。whileの括弧の 中はC言語とほぼ同じ演算子が使えます。条件分岐にはifやswitchがあります。 ifの使い方は

        # ifを使う
        if( $#argv < 1 ) then
            echo "using default file for input"
            myana default.dat
        else if( -e $1 ) then
            echo "using $1 for input"
            myana $1
        else
            echo "input file $1 not found"
        endif

if then、else、endifの構造は説明の必要はないでしょう。式の表現には初め て出てくるものがあります。$#argvは、argvという変数に含まれる文字列の数 を表します。argvは特別のシェル変数で、コマンド文字列に与えられた引数の 集合を表します。C言語のプログラミングのところで解説したものと同じargv です。このスクリプトが引数無しで呼び出されると$#argvは0です。この時は defaultを使うと言っています。次の$1は第1引数です。$ar gv[1]と同じ意味 です。$は変数参照でした。argvという変数を参照します。[1]はその変数の中 の1番目のワード(文字列)を表します。この例では引数としてファイル名を想 定しています。ところがifの括弧の中は論理式を想定しています。単に$1を書 いただけではうまく行きません。そこで-eという演算子を用います。その後の 名前のファイルが存在すれば真です。この種の演算子はよく使います。まとめ ておきましょう。

        -e filename     ファイルが存在すれば真

        -z filename     ファイルの寸法が0(空)なら真

        -d filename     ファイルがディレクトリであれば真

        -f filename     ファイルが通常のファイルであれば真

        -o filename     ユーザがそのファイルの持ち主であれば真

        -r filename     ユーザがそのファイルを読むことを許されていれば真

        -w filename     ユーザがそのファイルに書き込みを許されていれば真

        -x filename     ユーザがそのファイルの実行を許されていれば真

条件分岐には他にswitchがあります。これもC言語のswitch文と同じ使い方を します。

        # switchを使う
        while( 1 )
            echo -n "command: "
            set cmd = $<
            switch( $cmd )
            case quit:
                echo "exit from procedure"
                break;
            case help:
                echo "how to use this procedure..."
                breaksw
            default:
                echo "command $cmd not found"
                breaksw
            endsw
        end

この例ではswitchがwhileループの中で使われています。まずwhile(1)は常に 真ですから無限ループになります。つぎのecho -nは文字列command:を改行せ ずに表示します。コマンドプロンプトとして使っています。次のsetではcmdと 言う変数に$<という特殊な変数の持つ値を代入します。$<とは 標準入力から一行取り込むというものでスクリプトの中でユーザのキーボード 入力を受け付けるために用意されています。さて、やっとswitchまできました。 endswまでの間が対象になります。cmdの値がcaseの次のラベルと比較され一致 すればそこから実行します。どれにも一致しないときはdefault:から実行しま す。quitと一致したときはechoした後breakしています。これはwhileの無限ルー プから抜け出すことを意味します。switchの範囲に関する命令ではありません。 一方helpのときはbreakswしています。これはswitchの範囲から抜け出てendsw の次に飛ぶことを意味します。

繰り返しには他にforeachという命令もあります。

        # foreachを使う
        foreach input ( test.dat run003.dat run023.dat )
            echo "Try to analyze dataset ${input}"
            myana $input
        end

この例では変数inputにtest.dat、run003.dat、run023.datという文字列が順 に代入されe ndまでが繰り返されます。""の中でも$は変数参照として認識さ れます。foreachの括弧の中にワイルドカードを使うこともできます。上の例 でforeachの()の部分を( *.dat )とすると、現在のディレクトリの中にあるす べての.datファイルについて繰り返されます。

ここまでの例でおおかたの仕事はこなすことができると思います。あと必要と 思われるのはsleepでしょう。プロセスの実行を指定した秒数だけ休みます。 10秒休むには

        sleep 10

です。状態表示を繰り返したいときや会議の時間の予告など使い道は色々あり ます。次をやってみましょう。

        % ( sleep 300; echo "会議だよ!" ) &
        [1] 21044
        %

()の中は一つのプロセスとして扱われます。;は命令を順番に実行することを 指定します。まずsleepが実行されそれが完了するとechoが実行されます。パ イプ|とは動作が異なります。最後の&は()内のプロセスをバックグラウンドで 実行せよという意味です。5分経つと端末に「会議だよ!」と表示してくれま す。自分が実行させたバックグラウンドジョブが完了するのを待つwaitも覚え ておいてください。



next up previous contents
Next: シェルスクリプトの使い方 Up: シェルスクリプトを書く Previous: シェルスクリプトを書く



Kinya Hibino
Wed Apr 26 21:42:06 JST 1995