Shell Script ライトクックブック サポートページ

このページは,当研究所が発行致しました書籍「Shell Script ライトクックブック」をお買い上げ頂いた方向けの補足ページです.こちらで気付いた事,及び読者の方からご指摘があった事,さらに打ち込むのが面倒臭いリストを記載する予定です.


レシピ5.1: コマンド引数を処理する

このレシピで例示した,コマンド引数処理ルーチンを記します.

リスト

必要に応じてコピー&ペーストして使ってください.

コマンド引数処理ルーチン
# ↓必要に応じてデフォルト値を設定しておく
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"のようなもの)です.

レシピ7.5: 自ホストのIPアドレスを知る

このレシピで例示した,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コマンドは,表示フォーマットが環境によってまちまちなので工夫が必要なのです.

レシピ7.6: 絶対パスを知る

このレシピで例示した,"."や".."を含む相対パスを絶対パスに変換するスクリプトを記します.

リスト

必要に応じてコピー&ペーストして使ってください.

相対パスを綺麗に整形した絶対パス表記に変換するルーチン
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)の意味については本文を参照してください. まぁ,例え本書をお持ちでなくてもパターンをご覧になればそれぞれ何をやっているかなればわかりますよね.

第9章: Webアンテナ

本書でリストを公開したシェルスクリプト版「Webアンテナ」につきまして,使ってみたいが打ち込むのは面倒だとのご意見を頂きましたのでここでダウンロードできるように致しました.

ダウンロード

こちらからどうぞ.

Webアンテナとは?

本書をお読みになって頂いていない方のために簡単に説明します.

概要

このソフトはいわゆる「アンテナ」というやつです.指定したWebページで更新があった場合,それをアンテナのように察知して通知するものです.
通知はメールで行うようにしています.更新が激しいページではメールがいっぱい来ますので,必然的にこのアンテナはあまり更新しないページ向けといえるでしょう.
例として,「携帯電話各社が利用するIPアドレス帯域」ページを監視するようにしてあります.

必要なもの

このソフトはシェルスクリプトで掛かれていますのでまずシェルスクリプト(/bin/sh)が動く環境が必要になります.が,Webアクセスが必要ということで下記のソフトも必要になります.
このうち,明確にインストールが必要になるのは最初に挙げたのwgetでしょう.各OS・ディストリビューションでパッケージが用意されているのであればそちらからインストールするのが便利です.

使い方

0. 必要なソフトのインストール

上記のソフトで足りないものがあったら予めインストールしておきます.それから,MD5については先に述べたように各環境でコマンド名が違いますのでスクリプト本体の序盤にある変数"CMD_MD5"に正しいパスを書き込んでおきます.

1. スクリプトファイルを適当なディレクトリに置く

スクリプトファイル本体を適当なディレクトリに置きます.尚,そのディレクトリの直下にworkというディレクトリが作られ,監視対象のページが保存されますのでそれが可能なディレクトリに置きます.もし,スクリプトとworkディレクトリを別けたいのであれば…改造しましょう.(^^;) 簡単ですよ.
また,スクリプトファイルに実行パーミッションがなければセットしておきましょう.

2. 監視したいURLの登録

このスクリプトはお手軽なシェルスクリプトを利用しているということで,設定内容もプログラムと同じファイルにしてお手軽な設計になっていますのであしからず….
さて,まずは監視したいURLの登録です.スクリプトファイルの冒頭にある変数"URLs"にhttpから略さずに記入していきます.複数ある場合はスペース区切りです.

3. メールアドレスと共にコマンドを設置する

このコマンドは自力では定期的な監視を行ってくれません.cron等から定期的に実行されることを期待していますのでcrontabに登録します.この時,引数に通知したいメールアドレスを書いておきましょう.変更があるとそのアドレスに通知がなされるようになります.

おまけ: はなこ号のおすがた

本書の表紙モデルになって頂いたジャンボうさぎの「はなこ号」(撮影時9ヶ月の女の子)の取材写真です.

表紙元画像 表紙に採用したポーズ.
決め手は喉もとのおにく(マフラー)!
あとがき用 あとがきに採用したもの.
足が短いのがむしろかわいい.
おまけ1 せっかくなので「おまけ(その1)」.
耳を立てた直後に撮影.しかしその後10秒足らずでまた垂れる.
それにしても箱や腕と比べてみるとなんと巨大な….
おまけ2 「おまけ(その2)」.
落ち着きなさいって.そんな大きな体じゃ,
逃げたってすぐ捕まえられるんだから.
おまけ3 「おまけ(その3)」.
長いみみもさることながら,短いしっぽがまたうさぎらしい.




メニューに戻る…