SSIを使う(その2)


SSIから呼び出すプログラムは何でもかまわないわけだが、DOSのバッチファイルの感覚で使えて、機能的には1000倍くらい便利なシェルについてお話ししよう。
最近ではDOSのバッチファイルに馴染みのない方もおられようが、要はコマンドラインにコマンドをその都度打ち込んで実行する代わりに、それらのコマンドを記述したファイルを用意してそのファイルの内容に従ってコマンドを実行させるものである。
DOSのバッチファイルではさほど手の込んだことは出来ないが、これがunixのコマンドとなると話は変わる。
シェルにはshやcshなど数種類があり、近年まではcshが標準的に使われていた。
最近ではshを使うようになっているが、これは変数の代入操作などでcshは融通制が低いから,とも言われている。
(真相は知らない)FreeBSDにしろSolarisにしろshが標準になっており、以下でもshで話を進める。
なお、shでもcshでも代入操作や条件判断文などの書式が多少違うが、cshに慣れている人はcshで書けば良いだけの話である。


基本的には<!--#exec cmd="./hogehoge.sh"-->
から呼び出される,hogehoge.shの中身について説明することにしよう。
まずは最も簡単なhogehoge.shの中身。
#!/bin/sh      #shの場所を示す。

#単なるコメント
PREVYEAR=`/bin/date +%Y`
PREVMON=`/bin/date +%m`
PREVDATE=`/bin/date +%d`
echo "$PREVYEAR年$PREVMON月$PREVDATE"
これは見ての通り,日付を出力するシェルである。
PREVYEAR=`/bin/date +%Y'は、PREVDATEと言う名前の,勝手に作った変数の中に、date +%Yで示される,(すなわち10進数で示される年)を文字として格納しているわけだ。
PREVMON,PREVDATEも同様に、月と日を格納している。
最後の行のechoは、これらを表示するためのコマンドだ。
なお、変数が右辺に来る場合には"$"が付くというお約束がある。
上記シェルの実行結果が↓である。
本日は2024年03月28日です。
通常日付を打ち出すだけならシェルを使う意味は全く無い。
上記シェルと同じ結果を得るには<!--#config timefmt="本日は%Y年%m月%d日です。
"-->
<!--#echo var="DATE_LOCAL"-->
とするだけである(↓実行結果) 本日は2024年03月28日です

文字列日付の数値演算日付は文字列で与えられる。
処理の都合によっては、これを数値として扱いたい事もある。
例えば1ヶ月前の日付が欲しいような場合だ。
#!/bin/sh
PREVYEAR=`/bin/date +%Y`      #年をPREVYEARに格納する
PREVMON=`/bin/date +%m`      #月をPREVMONに格納する
PREVMON=`expr $PREVMON - 1`     #月を数値に変換(expr)して1を減じる
if [ $PREVMON = "0" ]; then     #もし引いた結果がゼロになるなら1月だから
PREVYEAR=`expr $PREVYEAR - 1`    #年から1を引いて
$PREVMON=12             #月を12月にする
fi                 #if文の終わり
if [ $PREVMON -lt 10 ]; then    #月が10より小さい(-lt)時は
PREVMON="0${PREVMON}"        #ゼロを付ける(05月とか)
fi                 #if文の終わり
echo "$PREVYEAR年$PREVMON月"
数値変換を行うとゼロサプレスされてしまうので、わざわざ"0"を付け足している。
上記シェルの実行結果が↓である。
先月は2024年02月でした。


shで使える環境変数shでは環境変数の取り込みや表示が簡単に行える。
以下のスクリプトをHTML上から呼び出してみていただきたい。
#!/bin/s
echo "Vars.print <br>"
echo GATEWAY_INTERFACE = &GATEWAY_INTERFACE "<br>"
echo REQUEST_METHOD = $REQUEST_METHOD "<br>"
echo SCRIPT_NAME = $SCRIPT_NAME "<br>"
echo QUERY_STRING = $QUERY_STRING "<br>"
echo SERVER_SPFTWARE = $SERVER_SOFTWARE "<br>"
echo SERVER_NAME = $SERVER_NAME "<br>"
echo SERVER_PROTOCOL = $SERVER_PROTOCOL "<br>"
echo SERVER_PORT = $SERVER_PORT "<br>"
echo HTTP_USER_AGENT = $HTTP_USER_AGENT "<br>"
echo HTTP_ACCEPT = $HTTP_ACCEPT "<br>"
echo PATH_INFO = $PATH_INFO "<br>"
echo PATH_TRANSLATED = $PATH_TRANSLATED "<br>"
echo REMOTE_HOST = $REMOTE_HOST "<br>"
echo REMOTE_ADDR = $REMOTE_ADDR "<br>"
echo REMOTE_USER = $REMOTE_USER "<br>"
echo REMOTE_IDENT = $REMOTE_IDENT "<br>"
echo AUTH_TYPE = $AUTH_TYPE "<br>"
echo CONTENT_TYPE = $CONTENT_TYPE "<br>"
echo CONTENT_LENGTH = $CONTENT_LENGTH "<br>"
環境変数の取り込みや表示はPerlでもCでも可能である。
また、文字列操作などに関してはPerlを使用するのが一般的だ。
shで文字列操作を行う場合にはawkやsedを呼び出しながらになるわけだが、それを行う必然性は余り感じられない。
sh,C,Perlなど、必要な機能によって使い分けるのが本筋というものだ。


unixのコマンドを使うunixコマンドを使わなければ、シェルはたいした機能を発揮しない。
かと言って、ここでunixのコマンドの説明をはじめたらキリがない。
でも何も書かないと何も分からないだろから、F&Fで雑記の更新に使っているスクリプトを紹介しておこう。
#! /bin/sh
#
MAINFILE=comment.htm           #トップページに表示される雑記
NEXTFILE=new_comment.htm          #更新する雑記
SEPAFILE=文間に入れるファイル.htm
#ディレクトリ指定の最後に"/"は付けないこと
DOCSHOME=/home/public_html        #フルパスで指定するドキュメントホーム
TEMPHOME=/home/public_html/temp      #フルパスで指定するテンポラリファイル用ディレクトリ
TEMPFILE1=tempfile1
TEMPFILE2=tempfile2
ZAKKIPREFIX=001  #雑記のファイル名,001-年月.htm とする。

ZAKKIEXTENS=.htm
# 取り除きたいタグを書いたファイル
REJECTFILE=reject.htm
# NEXTFILEが無い場合には更新しない
if test -f $DOCSHOME/$NEXTFILE then
# 日付の抽出
PREVYEAR=`/bin/date +%Y`
PREVMON=`/bin/date +%m`
PREVDATE=`/bin/date +%d`
PREVMONB=`expr $PREVMON - 1`
if [ $PREVMONB = "0" ]; then
PREVYEAR=`expr $PREVYEAR - 1`
$PREVMONB=12 fi if [ $PREVMONB -lt 10 ]; then
PREVMONB="0${PREVMONB}"
fi
if [ $PREVDATE = "1" ]; then
PREVMON=${PREVMONB}
fi
# テンポラリファイルをクリア
/bin/cp /dev/null $TEMPFILE1
/bin/cp /dev/null $TEMPFILE2
# テンポラリファイルにコピーして
/bin/cp $DOCSHOME/$MAINFILE $TEMPHOME/${TEMPFILE1}
# 余計なタグを取り除く
# grepはファイルや文字列の比較や加工を行うコマンド。
詳しくは man grep で見て欲しい。

# ここではREJECTFILEとMAINFILE中で一致したデータを取り除いている。
つまりREJECTFILE
# には取り除きたいタグが書いてあるというわけだ。

/bin/cat $DOCSHOME/$NEXTFILE | /usr/bin/grep -vf $DOCSHOME/$REJECTFILE > $DOCSHOME/$MAINFILE
# 文と文の間に入れるファイルを継ぎ足す準備をする
/bin/cp $DOCSHOME/${SEPAFILE} $TEMPHOME/$TEMPFILE2
# そのファイルを継ぎ足す。

# 一々テンポラリファイルを使うのは、元のファイルのに新たなファイルを足したい為。

# 下に加える場合はテンポラリファイルは必要ない
# catコマンドでは cat file1 >> file2 で、file2の先頭にfile1の情報が追加される。

/bin/cat $DOCSHOME/${ZAKKIPREFIX}-${PREVYEAR}${PREVMON}$ZAKKIEXTENS >> $TEMPHOME/$TEMPFILE2
# 雑記用ファイルにメインのファイルを足してテンポラリファイルに格納
/bin/cat $TEMPHOME/$TEMPFILE2 >> $TEMPHOME/$TEMPFILE1
# テンポラリファイルを雑記ファイルに書き戻す
/bin/mv $TEMPHOME/$TEMPFILE1 $DOCSHOME/${ZAKKIPREFIX}-${PREVYEAR}${PREVMON}$ZAKKIEXTENS
# 更新したらそのファイルを消しておく
/bin/rm $DOCSHOME/$NEXTFILE
fi
−−ここまで実際にF&Fで使用しているスクリプトは一日に何度も更新する場合に備えて、新しいファイルをバックナンバーにつなげずにトップページで表示されているものにつなげるようになっている。
このスクリプトはトップページ(通常はindex.html)から呼ぶ。
<BODY>
 <TITLE>なんじゃらかんじゃら</TITLE>
<H1>なんじゃらかんじゃらのホームページへようこそ</H1><BR>
*ここにメニューとか,更新しない部分を書いておく*#そしてシェルを呼び出す<!--#exec cmd="./auto_update.sh"-->
#雑記の部分をインクルードする<!--#include file="comment.htm"-->
日記のバックナンバーは<a href="zakki.htm">ここ</a>です</BODY>
(仮に上記スクリプトのファイル名をauto_update.shとした場合)これでページが参照される度にこのスクリプトが呼ばれるが、更新すべきファイル(例ではnew_comment.htm)が無い場合には何事も起こらない。
更新する場合はnew_comment.htmをアップロードして、index.htmlをリロードすればOKだ。
これでindex.htmlにインクルードされた部分は更新され、今まであったファイルはバックナンバーとしてファイルにアペンドされる。
バックナンバーのページはファイルをインクルードするだけだ。
<BODY>
 <TITLE>過去の日記の溜まり場</TITLE>
<!--#include file="001-9806.htm"-->
</BODY>
こんな感じだ。
*常識的なタグとか色指定は除いてあります,為念