いますぐ実践! Linuxシステム管理

[バックナンバーのトップへ] [Linux システム管理のトップへ]


いますぐ実践! Linux システム管理 / Vol.094 / 読者数:998名

こんばんは、うすだです。

またしても、子どもがインフルエンザにかかりました。
前もってインフルエンザの予防接種を受けたにも関わらず…ううむ。

今年も、小学校では、インフルエンザが大流行しているそうです。
病院の先生曰く、学級閉鎖しているクラスが結構あるとのこと。
実際、その病院にも、インフルエンザだと思われる子どもの患者さんが、 たくさんいました。待合室には、 インフルエンザがぎっしり詰まっていたような気がします。(ご用心ご用心…)

うちの子は体があまり強くないので、毎年インフルエンザにかかっては、 病院でお世話になっています。
そして、病院へ行く度に、同じようにインフルエンザな子どもがたくさんいて、 先生が今年は流行っているよとおっしゃっている気がします。

われわれが子どものころは、 こんな毎年のように大流行はしていなかったと思うのですが…。

年月とともに、いろんな変化があるのかもしれませんが、このような変化を感じると、 将来大丈夫なんだろうか、と不安になってしまいますね。

…のっけから暗い話ですみません。
そんなことは一瞬忘れて、今週も、はりきってまいりましょう!

今週のお題 - デーモンじゃないものをデーモンにする

システム管理でいろんな仕込みをやっていると、自分で作ったスクリプトを、 24時間365日常に動かしたくなるときがあります。

たとえば、パイプやソケットなどから読み出して処理を行ったり、 秒単位でなにかの監視を行ったりする必要があるときは、 それを行うプロセスがずっと動き続けてくれないと、困りますよね。

というわけで今週は、常時動作しないものを、 デーモンの如く動作させる方法について、ご紹介したいと思います。


まずは、今回常に動かす対象を、ここで決めておきたいと思います。

古い話で恐縮ですが、いにしえのころに、 syslog とパイプを使ってログをメールで通知する、というネタをご紹介しました。

Vol.017 - syslog を集中管理する (…の宿題の答え)
http://www.usupi.org/sysad/017.html

内容を、さらっとダイジェストでご紹介しますと…

/etc/syslog.conf に以下を追加すると、 /var/log/alert というパイプにログを出力してくれます。
(mkfifo /var/log/alert や kill -HUP `syslog.pid` もお忘れなく。)

  *.alert      |/var/log/alert

そして、以下のシェルスクリプトを用いて、先のパイプから読み出して、 メールで通知すると便利かもよー、という内容でした。

  #!/bin/sh
  while read message; do
      echo $message | /usr/bin/Mail -s 'syslog alert' root
  done < /var/log/alert

このスクリプトを、nohup コマンドで動作させましょうとか書いていたと思いますが、 今週は、別の方法で、動かし続けます。


では、その方法をご紹介しましょう。
それは、init に起動してもらうという方法です。

/etc/inittab に以下の1行を書いておくと、 init が指定したプログラムを起動してくれます。
しかも、そのプログラムが終了すると、繰り返し起動してくれますので、 不意に終了してしまったり終了させられたりしてしまっても、安心です。

  ID:ランレベル:respawn:起動するプログラム

ID には、他のエントリと重複しない1〜4文字を指定します。
ランレベルには、そのプログラムを起動したいランレベルを指定します。
respawn は、プログラムが終了したら、再び起動してもらうための指定になります。 他の指定もいくつかできますが、ここでは割愛します。
起動するプログラムは、起動したいプログラムですね。 引数がある場合はスペースで区切って羅列できます。

 

じゃあ、実際に設定してみましょう。

今回動かしたいスクリプトが、 /usr/local/sbin/syslog2mail.sh というファイルだった場合、 以下のような1行を /etc/inittab に追加します。

  alog:2345:respawn:/usr/local/sbin/syslog2mail.sh

そして、init に SIGHUP シグナルを送信して、 /etc/inittab を再度解釈してもらいます。

  # kill -HUP 1

init のプロセスID はぜったい 1 ですので、1 を指定しています。
これで、syslog2mail.sh が動き出しているはずです。

  # ps -C syslog2mail.sh
    PID TTY          TIME CMD
  18702 ?        00:00:00 syslog2mail.sh

きちんと動作するかどうか、logger コマンドで確認してみましょう。

  # logger -p local0.alert This is a test via logger.

と実行して、以下のような本文のメールが root 宛に届けば、成功です。

  Feb 25 22:37:50 server1 usu: This is a test via logger.

そして、試しに、syslog2mail.sh を kill してみましょう。

  # kill `ps -C syslog2mail.sh -o pid=`
  # ps -C syslog2mail.sh
    PID TTY          TIME CMD
   2963 ?        00:00:00 syslog2mail.sh

ちゃんと、新たな syslog2mail.sh が起動されていますね。


…とまあ、これはわりと一般的な方法ですので、 ご存知のかたもたくさんいらっしゃるかもしれません。

せっかくですので(?)、ここでは別の、変な方法をご紹介します。
それは、Apache を使う方法です。

Apache では、以下のように、ログをプログラムに渡すことができます。

  CustomLog "|/usr/bin/rotatelogs /var/log/access.log 86400" \
  combined

このプログラム(上記の場合 roatelogs です)は Apache から起動され、 kill しても、Apache が再びプログラムを起動してくれます。

…はい、つまり、これを利用してしまおうということですね。
ただ、そのままですと、標準入力にじゃんじゃんログを送りつけられますので、 ログを送られないように細工する必要があります。

それには、ありえない条件を SetEnvIf で指定して、 その条件が成立するときだけログを出力するように設定すれば、よさそうです。
というわけで、以下に例を示します。

  SetEnvIf Request_URI "^arienai$" arienai
  CustomLog "|/usr/local/sbin/syslog2mail.sh" combined env=arienai

要求された URI が "arienai" というときだけ、 syslog2mail.sh にログを出力します。 おそらく、ログが送られてくることはないでしょう。

ログの出力のための機能なのに、ログ以外のことに利用してしまうという時点で、 かなり間違っている気もしますが、init による方法が使えないときに、 ちょこっとご検討してみてはいかがでしょうか。


以上、スクリプトなどを常時動かす方法を、ご紹介しました。

/etc/inittab を眺めるとおわかりのように、respawn で常時起動されているものが、 けっこうあります。
自作に関わらず、どのようなものを常に動かすと便利になるか、 少し考えてみてはいかがでしょうか。

宿題の答え

先週の宿題は、

  今週(もー先週ですね)ご紹介した expect スクリプトを、以下のように
  変更してください。

  - 監視するサーバとサービスを引数で指定する。
  - 起動しているかどうかにかかわらず、標準出力に結果を表示する。

でした。

単刀直入に、回答例は以下の通りです。

  #!/usr/bin/expect
  set timeout 10
  log_user 0

  proc check_service {host service} {
      spawn telnet $host 12340
      expect {
          default {
              return "++ cannot connect: NG\r"
          } -re "Escape.*\.\n"
      }
      send "$service\r"
      expect {
          default {
              set ret "++ internal error: NG\r"
          } -re "\n(.*: NG.*)\nConnection" {
              set ret $expect_out(1,string)
          } -re "\n(.*: OK.*)\nConnection" {
              set ret $expect_out(1,string)
          }
      }
      return $ret
  }

  if {$argc == 0 || $argc % 2 != 0} {
      puts "Usage: $argv0 server services ..."
      exit 1
  }

  set result ""
  for {set i 0} {$i < [llength $argv]} {} {
      set host [lindex $argv $i]
      incr i
      set service [lindex $argv $i]
      incr i
      set ret [check_service $host $service]
      if {$ret != ""} {
          set result "$result+++ $host: $service\n$ret"
      }
  }
  puts $result
  if {[string match "*: NG*" $result]} {
      exit 2
  }

なんやかんや言って、前回の expect スクリプトとはあまり変わらないと思いますので、 説明は割愛させていただきます。

ちなみに、起動していないサービスがあると、終了ステータス 2 を返しますので、 失敗したときにメールで報告させることができます。
このファイルが /usr/local/sbin/servcheckarg.exp だった場合の例を、 以下に示します。(変数 T が未使用だという前提で書いています。)

  # T=`mktemp /tmp/srvchk-XXXXXXXX`; \
  (/usr/local/sbin/servcheckarg.exp server1 "httpd postfix" > $T \
  || mail -s "Check services" root < $T); rm -f $T; T=

おっと、csh 系の場合は、以下のようにしてください。

  # set T=`mktemp /tmp/srvchk-XXXXXXXX`; \
  (/usr/local/sbin/servcheckarg.exp server1 "httpd postfix" > $T \
  || mail -s "Check services" root < $T); rm -f $T; unset T

今週の宿題

今週の宿題は、

  /etc/passwd の状態を5秒毎に監視して、状態が変化したときメールで
  通知するスクリプトを作成して、常時動かしてみましょう。

です。

実用的にはいかがなものかという気もしますが、 とりあえず試しに作ってみようかって感じで、 トライしていただけますと幸いです。
状態は、ls -l の出力結果でよろしいのではないか、と思っております。

あとがき

1〜2年前までは、いわゆる成功本というやつを、よく読んでいました。
いわゆる、「成功マニア」なひとだったんだと思います。

目標を紙に書くとか、いろいろやってみたのですが、ご想像通り、 庶民のまま現在に至っております。

なんで成功しないのか、という疑問は、長く疑問に思いつつ蓋をしてきたわけですが、 最近、風呂に入っているときに、ふと気がつきました。

それは、

  自分を変えようという覚悟がないから成功しないのではないか、

ということです。

自分は今のまま変えずに、ただ単に書いてあることを、いや、書いてあることのうち、 今の自分にできることだけを実行して、成功できればなーと思っていました。

よく考えたら、そんなムシのいい話があるわけないですよね。
しかし、なんで今まで気がつかなかったのか、己の鈍感さに、 あらためてがっかりしました。

もうこの際、成功しなくてもいいので、自分を変えていくことを、 今から実践していきたいと思います。
(こういう中途半端な宣言をしているのが、いけないんですよね…。)

 

今週も、ここまで読んでいただき、ありがとうございました。
それでは、また来週に、お会いしましょう!

 

「いますぐ実践! Linux システム管理」の解除は、以下からできます。
http://www.usupi.org/sysad/ (まぐまぐ ID:149633)

バックナンバーは、こちらにほぼ全部そろっています。
http://www.usupi.org/sysad/backno.html

「栗日記」−最近、ちらほらと依頼が来るようになりました。
http://www.usupi.org/kuri/ (まぐまぐ ID:126454)
http://usupi.seesaa.net/ (栗日記ブログ)
http://www.fumido.co.jp/kuriniki/ (栗日記ぎゃらりー)


[バックナンバーのトップへ] [Linux システム管理のトップへ]

トップ

バックナンバー
    [日付順] [目的別]

プロフィール

▼ リンク

独学Linux
Linuxデスクトップ環境に関する情報が満載です。 メルマガもありますよ。
Server World
CentOS 6をサーバとしたときの設定例が、これでもかというくらいたくさん載っています。 CentOS以外のディストリビューション(Fedora, Ubuntu)も充実しています。
LINUXで自宅サーバーを構築・導入(Fedora9)
Fedora9のインストールの仕方から管理方法まで、詳しく載っています。 SearchManには情報がもりだくさんです。
マロンくん.NET
〜サーバ管理者への道〜
Linuxをサーバとして使用するための、いろいろな設定方法が載っています。 マロンくんもかわいいです。 なんといっても、マロンくんという名前がいいですね!!
日経Linux
今や数少なくなってしまったLinuxの雑誌。ニュースやガイドもあります。
Linux Square − @IT
@ITが提供する、Linux の情報が満載。 載っていない設定方法はないんじゃないでしょうか。
gihyo.jp…技術評論社
Linuxに限らず様々な技術情報が満載のサイト。 SoftwareDesign誌も、 ソフトウェア技術者は必見です。
SourceForge.JP Magazine
Linux に限らず、オープンソース関連の記事が網羅されています。
ITmediaエンタープライズ:Linux Tips 一覧
Tips というより FAQ 集でしょうか。わからないことがあれば覗きましょう。
IBM developerWorks : Linux
開発者向けですが、勉強になりますよ。
Yahoo!ニュース - Linux
Yahoo!のLinuxに関するニュース一覧です。
栗日記
システム管理とかと全然関係ありませんが、毎日栗の絵を描いています。
システム管理につかれちゃったとき、癒されたいときに、ご覧ください。:-)
WEB RANKING - PC関連
ランキングに参加してみました。押してやってください。

▼ 作ってみました

Add to Google

▼ せんでん




▼ 最近読んだ本

▼ 気に入ってる本