CSH Script入門


テキストファイルのうち

という2つの条件をともに満たすものは、『スクリプト』(script)と 呼ばれ、「実行可能ファイル」です。

スクリプトの最初の行の意味は次のようになっています。

スクリプトファイルの1行目の定義
#!プログラムのパス  コマンド引数1 コマンド引数2 ...
スクリプトが実行された場合は、「プログラムのパス」で表される プログラムを指定されたコマンド引数で起動して、ファイルの 残りの部分をそのプロセスの標準入力に与えます。

最初の例だと、「このファイルの2行目以下は /bin/csh が解釈して実行し、 /bin/csh を起動するときのオプションは -f である」という ことを意味しているわけです。

スクリプトは、スクリプトを解釈するプログラム名を先頭につけて 「○○スクリプト」と呼ばれることがあります。 たとえば、Cシェルが解釈するスクリプトは 「Cシェル・スクリプト」、 Perl が解釈するスクリプトは「Perlスクリプト」と呼ばれたりします。

Shellの種類

シェル(対話環境)では 「Borneシェル」と「Cシェル」が よく使われています。 初期のUnixの頃から使えたのがBorneシェルで、機能は単純ですが メモリをあまり多く消費しないので、スクリプトを書くのに 今でもよく使われています。 CシェルはUnixが発展していく過程で開発されたもので、 Borneシェルよりも高機能でCプログラミング言語に似た 文法が使えます。このため、Cを習得したユーザには使いやすく、 ユーザの標準のシェルとなっている場合が多いようです。 もっとも最近では、「Cシェル」にコマンドライン編集機能などを 追加して便利にした tcsh がよく使われるようになりましたが。

Borneシェルは sh というファイル名だったのですが、 GNU プロジェクトで同等な機能を持つシェルが新たに開発されて bash という名前が付けられています。 Linuxの多くのディストリビューションでは root の使うシェルは この bash が採用されています。

C-Shell Script

Cシェル・スクリプトについて説明します。

dirファイルの内容
#!/bin/csh -f
date
ls -l $*
dirファイルのパーミッション変更と実行
# chmod 755 dir
# ls -l dir
-rwxr-xr-x   1 nitta    nitta          28 Jun 18 18:57 dir
# ./dir
Sun Jun 18 18:58:55 JST 2000
total 1876
-rw-r--r--   1 nitta    nitta       11023 Apr 26 16:45 10baseT.gif
    ... 

C Shell Scriptの文法

set 変数名=値      ←変数への値を設定します。
${変数名}          ←変数の値を参照します。
$変数名            ←変数の値を参照します(後ろに空白がある場合はこれでも可)。

変数に対するパス名指定子

コマンド出力
指定子なしecho $cf/u/sam/common/gets.c
基本部分echo $cf:r/u/sam/common/gets
先頭部分echo $cf:h/u/sam/common
末尾部分echo $cf:tgets.c
拡張部分echo $cf:ec (BSD only)

エスケープすべきCシェルのMeta Character

記号意味
SPACE, TABコマンド引数の区切り文字
RETURNコマンド行の終り
$変数識別子
*[]?{}~-ファイル展開
> < & !入出力の切り換え
!^履歴
|パイプ
;コマンドの区切り
()コマンドグループ
\'"クォーティング
`コマンド置き換え
&バックグラウンドタスク

Cシェル引数の参照

記法意味
$#argv引数の数
$argv[*]全ての引数
$argv$argv[*]と同じ
$*$argv[*]と同じ
$argv[1-n]引数1からn
$0プログラムの名前
$argv[0]正しくない。$0を使うべきである
$argv[n]引数n (1<=n<=$#argv)
$1, $2, ..., $9
引数1,2, ...,9, $argv[1]から $argv[9]と同じ
$argv[$#argv]
最後の引数

Cシェルにおける if文の形式

1
if (expression) command
2
if (expression) then
    command(s)
endif
3
if (expressoin) then
    command(s)
else
    command(s)
endif
4
if (expressoin) then
    command(s)
[else if (expression) then
    command(s) ]
    ...
[else
    command(s)]
endif

代入演算子

記号意味
@ count = 6
echo $count
=exprの値をvarnameに格納する@ count = 00
+=exprの値をvarnameに加える@ count += 28
-=exprの値をvarnameから引く@ count -= 51
*=exprの値をvarnameにかける@ count *= 848
/=exprの値をvarnameで割る@ count /= 41
++varnameに1加える@ count ++7
--varnameから1引く@ count --5

算術、ビット、論理演算子

記号意味@num = 10のとき echo $r
+加算@ r = $num + 414
-減算@ r = $num - 55
*乗算@ r = $num * 10100
/整数の除算@ r = $num / 61
%剰余@ r = $num % 31
>>右シフト@ r = ($num >> 2)2
<<左シフト@ r = ($num << 2)80
~1の補数@ r = ~$num-11
!論理否定@ r = !$num0
|ビット毎のor@ r = ($num | 7)15
^ビット毎のxor@ r = ($num ^ 7)15

ファイル検査演算子 (-opr filename)

演算子(opr)意味
r読み出し可能
w書き込み可能
x実行可能
eファイルは存在する
oファイルの所有者
zファイルの長さは0
f普通のファイル(ディレクトリでない)
dディレクトリ

C-Shell Scriptの例

logをrotateする C-Shell Script は以下のようになります。

agelog
#!/bin/csh -f
if ($#argv == 1) then
    set filename=$1
    set age=3
else if ($#argv == 2) then
    set filename=$1
    set age=$2
else
    echo "usage: $0 filename [age]"
    exit -1
endif
set i=$age
set j=$age
@   j--
while ($i > 0)
    if (-e ${filename}.${j}) then
        mv ${filename}.${j} ${filename}.${i}
    endif
@   i--
@   j--
end
mv ${filename} ${filename}.0
touch ${filename}
exit 0

Yoshihisa Nitta

http://karel.tsuda.ac.jp/