3 最も単純な形のスクリプト

まずは今回目標とするスクリプトの最も単純な形のものを考えてみます。 指定する URL はその一覧ファイル (以後 URL リストファイル と呼びます) を用意しておいて、その各行にひとつずつ書くことにます。 そのファイルを仮に ~/wwwcheck/urllist としておきます (~ は、csh スクリプトではホームディレクトリを指します)。

~/wwwcheck/urllist の内容:
http://www.niit.ac.jp/
http://www.niit.ac.jp/ieehtml/iee/
...

wget で URL の HTML ファイルを取得するには、以下のようにします:

% wget -q -O - URL > HTMLFILE
ここで、指定している wget のオプションの意味はそれぞれ以下通りです。 よって、このようにすると取得した HTML ファイルは標準出力に出力されるので、 上のようにリダイレクションを利用してファイルに落とします。

今回の目標は、URL リストファイルの各行に書かれている URL を ひとつずつ wget に指定して HTML ファイルを取得すればいいので、 以下のような csh スクリプトでそれが実現できます。

wwwcheck1.csh の内容:
#! /bin/csh -f
##### 初期設定 ####
set urllistf = ~/wwwcheck/urllist # URL リストファイル
set datad = ~/wwwcheck/data # 取得したファイルの置き場所
set wget = "wget -q -O -"     # wget のコマンドライン
##### 実行部分 ####
set j=1
foreach url ( `cat $urllistf` )
    $wget "$url" > $datad/$j.html
    @ j ++
end

# で始まる行、また行の途中の # 以降はコメント部分で、 csh スクリプトでは無視されます。

先頭部分でいくつか初期設定をしていますが、 これらはもちろん右辺の値自体を 直接実行部分の方で使用するようにしてもよいのですが、 このようにしておけば、 後で修正をする場合、あるいは繰り返し利用する場合などに便利です。 set は、変数値の設定を行うコマンドですが、 2 つ目の wget のコマンドラインはスペースを含む文字列なので、 " " で囲まないと変数には文字列全体が保存されません。 それらの変数の値は $ をつけて参照します。

foreach はリストベースのループ構文で、

foreach var ( str1 ... strn )
    command1
    ...
end
の形式で使用し、 これは変数 var に文字列 str1 を代入して end までのコマンド列を実行し、 変数 var に次の文字列を代入して end までのコマンド列を実行し、 それを strn まで繰り返します。 wwwcheck1.csh の場合には変数 url に文字列が代入され、 その各 url に対し $wget@ で始まる 2 行が順次実行されることになります。

@ で始まる行は @ 文による計算代入式で、 ``@ j ++'' は変数 j の値をひとつずつ増やしますので、 ループの最初では j は 1 で、 よって $wget 文により $datad/1.html が生成され、 その後 @ 文により j は 2 になりますので、 ループの次の処理では $datad/2.html が生成される、 ということが繰り返されます。

ところで、url に代入される文字列ですが、これはリスト変数

( `cat $urllistf` )
の文字列が順に代入されています。 これがどのような文字列のリスト変数になっているのかを説明します。

まず、cat は Unix に標準的に用意されているコマンドで、

% cat file1 file2 ... filen
とすると、file1 の内容を標準出力に書き出し、 次に file2 の内容を書き出し、 これを filen まで繰り返すコマンドです。

一方、csh スクリプトで逆クォート ` ` で囲まれた部分は、 それをコマンドと見なして実行し、 その標準出力の、改行がスペースに置き換えられた文字列に展開されます。

例えばファイル file の中身が

str1 str2
str3
str4
であるファイルに対して、
( `cat file` )
とすると、これは
( str1 str2 str3 str4 )
と展開されます。

結局 wwwcheck1.csh では、url には URL リストファイル $urllistf の各行の内容、すなわち設定した URL がひとつずつ渡されて、 そのそれぞれに対して $wget の行が実行されることになります。

つまり、このスクリプトにより、 URL リストファイルの 1 行目の URL の HTML ファイルが 1.html に、 2 行目の URL の HTML ファイルが 2.html に、 次々と保存されていくことになります。

なお、$wget の行では変数 url の値を引用符で囲んでいますが、 これは、URL には特別な文字 `?' を含む場合があるからです (CGI によるページを参照する場合など)。 そのような URL の場合は、これを引用符 (" ") で囲んでおかないと、 その文字列が csh スクリプトのファイル名パターンと見なされて、 そのようなファイルが存在しない、というエラーが起きてしまいます。 単一引用符内 (' ') では変数の値は展開されませんが、 二重引用符内 (" ") ならば展開されます。

竹野茂治@新潟工科大学
2008年1月22日