このレシピで例示した,コマンド引数処理ルーチンを記します.
必要に応じてコピー&ペーストして使ってください.
コマンド引数処理ルーチン # ↓必要に応じてデフォルト値を設定しておく printhelp="0" ; verbose="NO" ; filename="" ; ipaddresses="127.0.0.1" arg_switch="" # ←引数を必要とするオプションの場合にオプションの値を覚える変数 for arg in "$@" do ### GNUでよく用いられる "--option=argument" 形式の分解 ##################### check1="${arg%%=*}" check2="${check1#--}" if [ \( "_$check1" != "_$arg" \) -a \( "_$check2" != "_$check1" \) ]; then arg_switch="$check1" arg="${arg#*=}" fi ### 引数を必要としないオプションおよび "-o a" 形式のオプション名解釈 ####### if [ -z "$arg_switch" ]; then ### # 引数を必要としないオプションの処理はここ if [ \( "_$arg" = "_-h" \) -o \( "_$arg" = "_--help" \) ]; then printhelp="1" # 例えばヘルプメッセージ表示 break elif [ \( "_$arg" = "_-v" \) -o \( "_$arg" = "_--verbose" \) ]; then verbose="YES" # 例えばverbose(冗長表示)スイッチ # 引数を必要とするオプションの場合,ここでオプション名を記録する else if [ "_${arg#-}" != "_$arg" ]; then arg_switch="$arg" else # ハイフン無しの引数を伴うオプションを許すなら # ここを有効にする #arg_switch="$arg" fi fi ### 引数を必要とするオプションの値の解釈 ################################### else # 記録されているオプション名に応じて次の引数を適切な変数に格納する if [ "$arg_switch" = "-f" ]; then arg_switch="" # そのオプションが必要な引数が1個なら arg_switch をクリア filename="$arg" # "-f"の後をファイル名と解釈する elif [ "$arg_switch" = "-i" ]; then # そのオプションが必要な引数が複数なら arg_switch は維持 ipaddresses="$ipaddresses $arg" # IPアドレスを複数格納する else # 知らないオプションが設定された場合はここに来るので必要ならヘルプを表示 printhelp="1" break fi fi done
様々な形式のオプションに対応したコマンド引数処理ルーチンの例です.旧来の形式("-o v"のようにオプション名の次がそのオプションの値)の他に,GNU形式("--option=value"のように オプション名=値 になっているもの),引数をとらないオプション("-o"や"-option"など)やハイフン無しのオプション("o"など)に対応しています. 対応していないのは,オプションが連続するもの(例えば"ps -aef"のようなもの)です.
このレシピで例示した,ifconfigコマンドからIPアドレスを取得する関数を記します.
必要に応じてコピー&ペーストして使ってください.
ifconfigコマンドから自ホストのIPアドレス(IPv4)を取得する関数 # ----- comfirm linking up ----- # arg : $1 ... interface name # result: 0=The specified interface has gotten an IP address. # (An IP address is in "ipaddr" variable.) # 1=The specified interface has not been able to get an IP address. # 2=The specified interface name is invalid. confirm_linkingup() { local PATTERN_IPV4_BW_MATCH local check local result # The result of this function (See the upper) local ifconfig_output # STDOUT from ifconfig command local inet_status # 0:"inet" will be not found yet. # 1:"inet" has been found now. # 2:"inet" has been found ago. PATTERN_IPV4_BW_MATCH="[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\$" result=1 ifconfig_output=`ifconfig $1 2> /dev/null` if [ $? -eq 0 ]; then inet_status=0 for check in $ifconfig_output; do if [ $inet_status -le 1 ]; then if [ $inet_status -eq 0 ]; then if [ "${check#inet}" = "$check" ]; then continue fi fi check=`echo $check | grep -E $PATTERN_IPV4_BW_MATCH` if [ -n "$check" ]; then ipaddr="$check" result=0 break else inet_status=`expr $inet_status + 1` fi else result=1 break fi done else result=2 fi return $result }
引数としてインターフェース名(Linux等では"eth0"などですね)を与え本関数を呼びます.すると内部でifconfigコマンドを実行して,戻り値を返します.
戻り値が0の場合は取得成功,0以外の場合はIPアドレスが振られていないなどの理由で取得失敗です.成功している場合は変数"ipaddr"に取得したIPアドレスが入っています.
この関数の特徴は多くの環境(OS・ディストリビューション)でIPアドレスを正しく取得できるように工夫してあることです.ifconfigコマンドは,表示フォーマットが環境によってまちまちなので工夫が必要なのです.
このレシピで例示した,"."や".."を含む相対パスを絶対パスに変換するスクリプトを記します.
必要に応じてコピー&ペーストして使ってください.
相対パスを綺麗に整形した絶対パス表記に変換するルーチン pathname=TARGET_PATH ← ここに対象パス名を設定 #カレントパスの後に付加する pathname="`pwd`/$pathname" #(1)を実施 (1)〜(8)の意味については後述 pathname=`echo -n "$pathname" | sed 's/\/\{2,\}/\//g'` #(2)を実施 pathname=`echo -n "$pathname" | sed 's/\/$//'` pathname0="" while [ "$pathname" != "$pathname0" ]; do pathname0="$pathname" #(3)を実施 pathname=`echo -n "$pathname" | sed 's/\/\.\//\//'` #(4)を実施 pathname=`echo -n "$pathname" | sed 's/\/\.$//'` done pathname0="" while [ "$pathname" != "$pathname0" ]; do pathname0="$pathname" #(7)を実施 pathname=`echo -n "$pathname" | sed 's/^\/\.\.\//\//'` if [ "$pathname" != "$pathname0" ]; then continue fi #(8)を実施 pathname=`echo -n "$pathname" | sed 's/^\/\.\.$/\//'` if [ "$pathname" != "$pathname0" ]; then break fi #(5)を実施 pathname=`echo -n "$pathname" | sed 's/\/[^\/]\{1,\}\/\.\.\//\//'` if [ "$pathname" != "$pathname0" ]; then continue fi #(6)を実施 pathname=`echo -n "$pathname" | sed 's/\/\([^\/]\{1,\}\)\/\.\.$//'` done # ヌルになっていたら"/"とする [ -z "$pathname" ] && pathname="/"
"././HOGE/../../FOO//BAR"のような相対パスをpwdコマンドとパターンマッチングによって絶対パスに直します.(1)〜(8)の意味については本文を参照してください. まぁ,例え本書をお持ちでなくてもパターンをご覧になればそれぞれ何をやっているかなればわかりますよね.
本書でリストを公開したシェルスクリプト版「Webアンテナ」につきまして,使ってみたいが打ち込むのは面倒だとのご意見を頂きましたのでここでダウンロードできるように致しました.
こちらからどうぞ.
本書をお読みになって頂いていない方のために簡単に説明します.
概要
このソフトはいわゆる「アンテナ」というやつです.指定したWebページで更新があった場合,それをアンテナのように察知して通知するものです.
通知はメールで行うようにしています.更新が激しいページではメールがいっぱい来ますので,必然的にこのアンテナはあまり更新しないページ向けといえるでしょう.
例として,「携帯電話各社が利用するIPアドレス帯域」ページを監視するようにしてあります.
必要なもの
このソフトはシェルスクリプトで掛かれていますのでまずシェルスクリプト(/bin/sh)が動く環境が必要になります.が,Webアクセスが必要ということで下記のソフトも必要になります.
このうち,明確にインストールが必要になるのは最初に挙げたのwgetでしょう.各OS・ディストリビューションでパッケージが用意されているのであればそちらからインストールするのが便利です.
使い方
0. 必要なソフトのインストール
上記のソフトで足りないものがあったら予めインストールしておきます.それから,MD5については先に述べたように各環境でコマンド名が違いますのでスクリプト本体の序盤にある変数"CMD_MD5"に正しいパスを書き込んでおきます.
1. スクリプトファイルを適当なディレクトリに置く
スクリプトファイル本体を適当なディレクトリに置きます.尚,そのディレクトリの直下にworkというディレクトリが作られ,監視対象のページが保存されますのでそれが可能なディレクトリに置きます.もし,スクリプトとworkディレクトリを別けたいのであれば…改造しましょう.(^^;) 簡単ですよ.
また,スクリプトファイルに実行パーミッションがなければセットしておきましょう.
2. 監視したいURLの登録
このスクリプトはお手軽なシェルスクリプトを利用しているということで,設定内容もプログラムと同じファイルにしてお手軽な設計になっていますのであしからず….
さて,まずは監視したいURLの登録です.スクリプトファイルの冒頭にある変数"URLs"にhttpから略さずに記入していきます.複数ある場合はスペース区切りです.
3. メールアドレスと共にコマンドを設置する
このコマンドは自力では定期的な監視を行ってくれません.cron等から定期的に実行されることを期待していますのでcrontabに登録します.この時,引数に通知したいメールアドレスを書いておきましょう.変更があるとそのアドレスに通知がなされるようになります.
本書の表紙モデルになって頂いたジャンボうさぎの「はなこ号」(撮影時9ヶ月の女の子)の取材写真です.