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

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


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

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

登録したら、大抵は、そのページの URL を、自分でメモしておきます。
あとで、変更や解除をするときのために記録するわけですが、うっかり、 メモし忘れることが、たまにあります。
そんなところの登録を変更したり解除したくなったとき、 検索で見つかる場合もありますが、発見できないことも、 ごくまれにですが、あります。

登録したときの情報を、どこかで集中管理しておけばいいんだよなぁ…。
と考えていたときに、ふと思いつきました。

登録したら、自分のブログのどこかに(登録サイトが)トラックバックしてくれれば、 そこを参照するだけで済むのではないか、ということに。

ブログなんて、いまどきどこででも無料で作れますので、 あとは非公開のページにトラックバックしてくれれば、 すぐ実現できると思うのですが、いかがでしょうか。

…とまあ、アイデアとしてどうなのかさっぱりわかりませんが、 せっかく思いついたので、ここに記してみました。

書いてすっきりしたので、今週もはりきってまいりたいと思います。

今週のお題 - 対話型アプリケーションを自動実行する

24時間365日戦い続けるシステム管理者にとって、 自動化は永遠のテーマであると言えます。
自動化できる作業を、スクリプトを書いて cron で定期的に実行するようにできれば、 ネコの手も借りたいほどの忙しさが、緩和されます。

しかし、対話型のアプリケーションの場合、 本来人間が入力すべき文字をリダイレクトで渡しても、 うまく動作してくれないことが多々あります。
たとえば、telnet コマンドを使って、SMTP でメールを送りたいとき、

  #!/bin/sh
  telnet localhost smtp << E-O-F
  HELO localhost
  MAIL FROM:<usu@usupi.org>
  RCPT TO:<kuri@usupi.org>
  DATA
  From: usu@usupi.org
  To: kuri@usupi.org
  
  test.
  .
  QUIT
  E-O-F

というスクリプトを作って実行しても、SMTP のコマンドが、 タイミングよく渡されることはなく、満身の力を込めて振ったバットは、 虚しく宙を舞ってしまいます。

しかし、だからといって諦めていてはいけません。
ちゃんと、それを解決するための手段が、世の中にはあるのです。
せっかくあるのだから、それを使わない手はありませんよね。

というわけで、今週は、対話型アプリケーションを自動的に実行するための方法を、 ご紹介したいと思います。


今週は、expect というコマンドを使用します。
expect は、Tcl/Tk のアプリケーションを自動的に実行し、 テストを行うためのツールです。
ですが、別に Tcl/Tk を使っていないアプリケーションでも、 使えるようにできています。ありがたいことですね。

幸い、大抵のディストリビューションには、expect パッケージが存在します。 ただし、デフォルトではインストールされないようですので、

  # yum install expect

とか、

  # apt-get install expect

などと実行して、入れておいてください。


それではまず、簡単な使い方から、ご紹介したいと思います。

expect コマンドをそのまま実行しますと、対話形式で操作できるようになっています。

  % expect
  expect1.1>

こんなふうにプロンプトを出力して、指示待ち君の状態になります。
ちょっと試すときにはいいのですが、これだと説明しづらいので、 今回はスクリプトファイルを書いて実行するという形式で、 ご紹介していきたいと思います。

 

というわけで最初は、簡単なところから。
以下の内容のファイルを、テキストエディタ等で作成してみてください。

  #!/usr/bin/expect
  spawn /bin/date
  expect eof

作成したら、chmod コマンドで実行可能な形式にして、実行します。
たとえば、このファイルの名前が test1 なら、以下のようにします。

  % chmod +x test1
  % ./test1
  spawn /bin/date
  2007年  2月  4日 日曜日 18:59:09 JST

これは、spawn という命令で /bin/date を実行し、expect eof で終了を待つだけの、 超簡単なスクリプトです。

date コマンド自体はぜんぜん対話形式ではありませんが、基本的には、 このような形式で記述していきます。


それでは、もう少しましなスクリプトを作ってみましょう。
以下は、telnet コマンドを使って、www.usupi.org から HTTP で RSS (/kuri/index.rdf) を取得するためのスクリプトです。

  #!/usr/bin/expect
  set host www.usupi.org
  set path "/kuri/index.rdf"
  spawn telnet $host 80
  expect "Escape"
  send "GET $path HTTP/1.1\rHost: $host\rConnection: close\r\r"
  expect eof

最初の set host www.usupi.org で、変数 host に www.usupi.org を代入しています。 path も同様です。以降で出てきますが、変数名の先頭に $ をつけると、 変数を参照できます。

そして、次の4行目の spawn で、telnet コマンドを起動します。
5行目の expect では、 telnet コマンドから "Escape" という文字を含む応答があるまで待ちます。
直接 telnet コマンドを実行しますと、

  % telnet www.usupi.org 80
  Trying 59.106.23.151...
  Connected to www.usupi.org.
  Escape character is '^]'.

という応答が得られますが、これの最後の Escape character ... の1行を待っているわけですね。
Escape 云々が得られたタイミングで、6行目の send を用いて、 HTTP の GET メソッドを出力します。
出力したら、あとは WWW サーバからの応答を、expect eof により、 最後まで待ちます。

というわけで、test2 という名前でスクリプトを保存したら、 以下のように実行してみましょう。

  % chmod +x test2
  % ./test2
  spawn telnet www.usupi.org 80
  Trying 59.106.23.151...
  Connected to www.usupi.org.
  Escape character is '^]'.
  GET /kuri/index.rdf HTTP/1.1
  Host: www.usupi.org
  Connection: close

  HTTP/1.1 200 OK
  ...後略...

ようやく、 対話型アプリケーションの自動化っぽい領域に踏み入ることができましたね。
でも、できれば、WWW サーバやパスを引数で指定できるようにして、 汎用化したいところです。

じゃあ、そのようにしてみましょう。
以下は、先ほどのスクリプトをもとにして、引数に、 WWW サーバとパスを指定できるようにしたものです。

  #!/usr/bin/expect
  if {$argc != 2} {
      puts "Usage: $argv0 host path"
      exit
  }
  set host [lindex $argv 0]
  set path [lindex $argv 1]
  spawn telnet $host 80
  expect "Escape"
  send "GET $path HTTP/1.1\rHost: $host\rConnection: close\r\r"
  expect eof

$argc および $argv は、あらかじめ用意された変数で、それぞれ、 引数の個数と引数が代入されています。 引数に、WWW サーバ名とパスを必要としますので、 2行目で $argc が 2 であることを確認しています。
$argc が 2 でない場合は、3行目の puts で使用方法を出力し、 exit で終了します。ちなみに、$argv0 はスクリプト自身が代入されています。

そして、6〜7行目で、host と path に引数の値を代入しています。
$argv に引数すべてが含まれていますので、lindex で取り出します。
8行目の spawn 以降は、先ほどと同様です。

このスクリプトが test3 だった場合の使用例を、以下に示します。

  % chmod +x test3
  % ./test3
  Usage: ./test3 host path
  % ./test3 www.google.co.jp /
  spawn telnet www.google.co.jp 80
  Trying 72.14.253.147...
  Connected to www.google.co.jp.
  Escape character is '^]'.
  GET / HTTP/1.1
  Host: www.google.co.jp
  Connection: close

  HTTP/1.1 200 OK
  ...後略...

以上、expect の簡単な使い方を、ご紹介しました。

ご紹介した内容が、あまり実用的でなかったかもという気がしておりますが、 他にも、fsck や ftp などの自動実行ができるようになると思いますので、 だまされたと思って、いろいろとお試しくださいまし。
(何か聞いてくる configure スクリプトの自動実行にも使えそうです。)

今週は、簡単な使い方で終わってしまいましたので、次週は、 もうちょい踏み込んだ内容をお届けしたいと思っております。乞うご期待…!?

宿題の答え

先週の宿題は、

  RAID5 で構成されたMDデバイスで、パーティションが1つ壊れた場合に
  書き込みを行うと、どうなるでしょうか。

でした。

それでは、試してみましょう。
以下のように、いまは正常な状態です。

  # cat /proc/mdstat
  Personalities : [raid5] [raid4]
  md0 : active raid5 hdb3[2] hdb2[1] hdb1[0]
        65280 blocks level 5, 64k chunk, algorithm 2 [3/3] [UUU]
      
  unused devices: <none>

ここで、hdb3 を使えなくします。

  # mdadm /dev/md0 -f /dev/hdb3
  mdadm: set /dev/hdb3 faulty in /dev/md0

この状態で、マウントしているディレクトリに、書き込みを行います。
/mnt/data にマウントしているとして、試しに、/boot 以下をコピーしてみましょう。

  # tar cf - boot | (cd /mnt/data; tar xfp -)

…あ、あれ、とくに何も起こりませんね…。
キャッシュ上にあって、/dev/md0 に書かれていないからではないか、と思い、 sync や umount してみましたが、特に問題なく実行されました。
再度マウントして書き込んだりしましたが、問題なくアクセスできます。

では、さらにもう1つ使えなくなると、どうでしょうか。
と思って1つ外し、書き込んでみたところ、すぐに、

  Buffer I/O error on device md0, logical block 数字
  lost page write due to I/O error on md0

というエラーが大量に出力されました。
さすがに、1つだけではダメなようです。

というわけで、確証を得たわけではないところがなんとも言えないところですが、 1つ足りないだけならなんとかなりそうな予感です。
…ですが、最悪の事態にならないよう、なるべく使用しないようにして、 早急に代わりのディスクに差し替えてくださいませ。
(新たな現象や証拠が発見され次第、再度ご紹介させていただきます。)

今週の宿題

今週の宿題は、

  telnet コマンドを用いて、SMTP でメール送信する expect スクリプト
  を作成してください。

です。

冒頭の、動作しないシェルスクリプトを、expect で動作するようにしてみてください。 余力があれば、送信先などを引数から得られるようにすると、よいかもですよ。

あとがき

突然ですが、Open Tech Press をみていて、面白い記事を発見しました。

インターネット接続の高速化と安全化をもたらす OpenDNS
http://opentechpress.jp/developer/07/02/02/0130245.shtml

上記は、OpenDNS という、無料で使える DNS サービスの紹介記事です。
OpenDNS を使えば、以下の恩恵が受けられるようになるそうです。

  1. 大量のキャッシュと負荷分散による、高速なパフォーマンス。
  2. ドメイン名のタイプミスの自動補正。
  3. フィッシングサイトへのアクセスをブロック。

実際に試してみますと、確かに、名前の解決が速くなりました。
2. も、たとえば、http://www.usupi.og/ と、間違ったサイトにアクセスすると、 http://www.usupi.org/ に自動修正してくれました。 微妙なミスの場合は、OpenDNS のサイトにつながり、候補を挙げてくれました。
(3. は、フィッシングサイトがわからないので未確認です…。)

で、これを利用するには、ソフトをインストールする必要はありません。
ただ単に、OpenDNS の DNS サーバを設定するだけです。
つまり、/etc/resolv.conf を以下のようにするだけで、 OpenDNS を利用できてしまうのです。

  nameserver 208.67.222.222
  nameserver 208.67.220.220

世の中には、いろんなサービスがものすごくたくさんありますが、 OS を問わないサービスというと、WWW 上で構築されたものだったりします。
でも、OpenDNS の場合、利用したければ、 OpenDNS の DNS サーバを設定するだけでいいわけですよ。 まさに、OS を問わないサービスです。

こんな根本的なところに、新規なサービスが存在するとは、個人的には、 ものすごい衝撃でした。やられたっ!!! って感じでした。
がんばって考えれば、まだまだ面白いことを思いつく余地があるのかも、 という気にさせられました。諦めずにがんばろうと思います。

 

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

 

「いますぐ実践! 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

▼ せんでん




▼ 最近読んだ本

▼ 気に入ってる本