システム管理者のための Python

システム管理を簡単に (そしてもっと楽しく) する

Python を導入して、UNIX システムを管理するとともに優れたプログラム設計の概念を取り入れてください。学習しやすいオープンソースのスクリプト言語、Python は、システム管理者のジョブを迅速に行えるようにするだけでなく、管理作業をもっと楽しいものに変えてくれます。

James Knowlton (james@jamesknowlton.com), Software Quality Engineer, Freelance Writer

Photo of James KnowltonJames Knowlton は、ADP (Automated Data Processing), Inc. のソフトウェア品質管理技術者です。ADP のコンピューター・テレフォニー・インテグレーションおよびネットワーク・ビデオ・プロジェクトの品質保証に対する取り組みを先導する彼は、Python、Ruby、PHP、Apache、MySQL など、広範なオープン・ソース技術の経験を豊富に積んでいます。



2007年 9月 07日 (初版 2007年 9月 04日)

はじめに

システム管理者に突きつけられる課題と問題は数え切れません。ユーザーや、ディスク・スペース、プロセス、デバイス、バックアップの管理が原因で髪が薄くなったり、笑いや正気を失うシステム管理者も数多くいることでしょう。シェル・スクリプトは助けになりますが、苛立たしい制約があることも珍しくありません。そんなときに活躍するのが、厄介な作業を簡単でしかも (あえて言うのなら) 楽しいものに変えるフル装備のスクリプト言語、Python です。

この記事では例を用いて、実用化できる Python のさまざまな機能を説明します。ここで紹介する例をひと通り試してみれば、Python の実力を理解できること間違いありません。

モジュールについて

モジュールは Python の重要な概念です。基本的に、モジュールとはインポートして使用するリソースのことを指します。このインポート・プロセスは、例えるならファイル・キャビネットから 1 枚の紙を取り出し、すぐに使用できるように机の上に置いておくことのようなものです。モジュールをインポートするには、各サンプル・プログラムの先頭にある import コマンドを使用します。データベース接続、ネットワーク・プログラミング、オペレーティング・システム・サービスをはじめ、その他何百もの有用な分野を対象としたモジュールが用意されています。


Python を動作させる

Python を使う理由

Python にはこれを推奨する理由となる数多くの特徴があります。

  • 無料のオープン・ソースであること。
  • 学習しやすいこと。構文が他のスクリプト言語より遥かに英語に似ているという印象を受けるユーザーは大勢います。
  • 完成度が高いこと。Python が登場してから、すでに長い時間が経っています。つまり、そのコードが安定していること、多数のモジュールによって機能が追加されていること、しっかり作られているドキュメントを Web で入手できることを意味します。

Python はフル装備の堅牢なプログラミング言語です。したがって、備わっている機能も膨大な数にのぼり、Python を学ぶのは壮大なスケールの作業となり得ます。しかし、GUI ツールキットをはじめとする Python の多くの機能は、システム管理者にとっては限られた価値しかないということを覚えておいてください。この記事で具体的な例を使用しているのは、このような理由からです。これらの例を見れば、システム管理用の Python スクリプトを効果的に作成するために必要となるスキルがわかります。

例についての注意事項

  • それぞれの例では、try: と an except: を中心にコードのブロックを記載しています。これはあくまでも基本的なエラー処理の実装です。Python はあらゆるタイプの例外を処理するための広範なサポートを備えていますが、この記事のサンプル・プログラムでは簡潔なエラー処理にとどめています。
  • ここで紹介する例は Linux® ボックスで動作する Python 2.5 で実行しましたが、どの UNIX®/Linux マシンでも機能するはずです。
  • 読者の皆さんは間違いなく、ここに記載したスクリプトを改良する方法を思い付くでしょう。それがまさに Python スクリプトの本質です。Python のスクリプトは、コードを再コンパイルしなくても簡単に変更やカスタマイズができるようになっています。

例 1: ファイルを検索し、アクセス権をわかりやすいフォーマットで表示する

最初のサンプル・プログラム (リスト 1 を参照) は、(ユーザー入力に基づく) パターンと一致するファイルを検索し、検索結果と併せてその特定のファイルに割り当てられたアクセス権を画面に表示します。第一印象では、このプログラムの機能は find コマンドとさほど変わらないと思うかもしれませんが、このプログラムの場合、結果をカスタマイズして表示することができ、その方法には限りがありません。この例では、システム・コマンドを改良する (改良とまではいかなくても、よりカスタマイズする) 方法を示しています。

基本的に、このスクリプトは以下の 3 つの作業を行います。

  1. ユーザーから検索パターンを取得する。
  2. 検索を実行する。
  3. ユーザーに検索結果を表示する。

スクリプトを作成する際には、「このコードはどの作業をサポートするのか」と絶えず自問自答してください。この自問自答が、作業の目的を絞り込んで効率を上げることになります。

リスト 1. ファイルの検索と検索結果およびアクセス権の一覧表示
import stat, sys, os, string, commands

#Getting search pattern from user and assigning it to a list

try:
    #run a 'find' command and assign results to a variable
    pattern = raw_input("Enter the file pattern to search for:\n")
    commandString = "find " + pattern
    commandOutput = commands.getoutput(commandString)
    findResults = string.split(commandOutput, "\n")

    #output find results, along with permissions
    print "Files:"
    print commandOutput
    print "================================"
    for file in findResults:
        mode=stat.S_IMODE(os.lstat(file)[stat.ST_MODE])
        print "\nPermissions for file ", file, ":"
        for level in "USR", "GRP", "OTH":
            for perm in "R", "W", "X":
                if mode & getattr(stat,"S_I"+perm+level):
                    print level, " has ", perm, " permission"
                else:
                    print level, " does NOT have ", perm, " permission"
except:
    print "There was a problem - check the message above"

このプログラムは、以下のステップに従います。

  1. ユーザーに検索パターンを要求する (7 行目~ 9 行目)。
  2. 検出したファイルの一覧を出力する (12 行目~ 14 行目)。
  3. stat モジュールを使用して、検出されたファイルごとのアクセス権を取得し、画面に表示する (15 行目~ 23 行目)。

このプログラムを実行すると、リスト 2 のような結果が出力されます。

リスト 2. 最初の例の出力
$ python example1.py
Enter the file pattern to search for:
j*.py

FILES FOUND FOR PATTERN  j*.py :
jim.py
jim2.py
================================

Permissions for file  jim.py :
USR     R
USR     W
USR     X
GRP     -
GRP     -
GRP     -
OTH     -
OTH     -
OTH     -

Permissions for file  jim2.py :
USR     R
USR     W
USR     X
GRP     R
GRP     -
GRP     X
OTH     R
OTH     -
OTH     X

例 2: tar アーカイブでのメニューで選択された操作を実行する

前の例では使用する検索パターンをユーザーに入力するよう要求しましたが、コマンドラインの引数によってユーザーから情報を取得するという方法もあります。Python でのこの方法を説明しているのが、リスト 3 のプログラムです。このコードは、tar ファイル名をコマンドラインの引数として使用し、ユーザーに複数のオプションを提示します。

この例では、問題に対する新しい方法も示されています。最初の例では commands モジュールを使用して find コマンドを実行し、その出力をキャプチャーしましたが、この手法では体裁が整わない場合があり、また「Python 的」な手法とも言えません。この例では tarfile モジュールを使用して tar ファイルを開くため、ファイルを操作するときに Python の属性とメソッドを使用できるという利点があります。このように Python が提供するさまざまなモジュールを使えば、コマンドラインからでは実行できないことでも実行できます。

この例は、Python にメニュー・システムを実装する場合の好例です。プログラムは以下のように、ユーザーの選択に応じてさまざまなアクションを実行します。

  • 1 を押すと、プログラムは現行ディレクトリーの抽出先とするアーカイブ内のファイル名を入力するようプロンプトを出し、該当するファイルを抽出します。
  • 2 を押すと、プログラムはファイル名を入力するようプロンプトを出し、該当するファイルの情報を表示します。
  • 3 を押すと、プログラムはアーカイブに含まれるすべてのファイルを一覧表示します。
リスト 3. tar アーカイブでのメニューの選択に応じたアクションの実行
import tarfile, sys

try:
    #open tarfile
    tar = tarfile.open(sys.argv[1], "r:tar")

    #present menu and get selection
    selection = raw_input("Enter\n\
    1 to extract a file\n\
    2 to display information on a file in the archive\n\
    3 to list all the files in the archive\n\n")

    #perform actions based on selection above
    if selection == "1":
        filename = raw_input("enter the filename to extract:  ")
        tar.extract(filename)
    elif selection == "2":
        filename = raw_input("enter the filename to inspect:  ")
        for tarinfo in tar:
            if tarinfo.name == filename:
                print "\n\
                Filename:\t\t", tarinfo.name, "\n\
                Size:\t\t", tarinfo.size, "bytes\n\
    elif selection == "3":
        print tar.list(verbose=True)
except:
    print "There was a problem running the program"

このプログラムは、以下のステップに従います。

  1. tar ファイルを開く (5 行目)。
  2. メニューを表示し、ユーザーに項目を選択させる (8 行目~ 11 行目)。
  3. 1 が押された場合 (14 行目~ 16 行目)、アーカイブからファイルを抽出する。
  4. 2 が押された場合 (17 行目~ 23 行目)、選択されたファイルに関する情報を表示する。
  5. 3 が押された場合 (24 行目~ 25 行目)、アーカイブに含まれるすべてのファイルに関する情報を表示する。

出力結果をリスト 4 に記載します。

リスト 4. 2 番目の例のユーザー・メニュー
$ python example2.py jimstar.tar
Enter
1 to extract a file
2 to display information on a file in the archive
3 to list all the files in the archive

例 3: 実行中のプロセスを確認し、わかりやすいフォーマットで情報を表示する

システム管理者の最も重要な務めの 1 つは、実行中のプロセスを確認することです。リスト 5 のスクリプトを見ると大体わかるように、このプログラムはコマンドによって生成された出力で grep コマンドを実行できるという UNIX の機能を利用して、Python が解析しなければならないデータを自動的に絞り込んでいます。

このプログラムでは string モジュールも使用しています。このモジュールは頻繁に使うことになるので、よく理解しておいてください。

リスト 5. 実行中のプロセスに関する情報のわかりやすいフォーマットでの表示
import commands, os, string

program = raw_input("Enter the name of the program to check: ")

try:
    #perform a ps command and assign results to a list
    output = commands.getoutput("ps -f|grep " + program)
    proginfo = string.split(output)

    #display results
    print "\n\
    Full path:\t\t", proginfo[5], "\n\
    Owner:\t\t\t", proginfo[0], "\n\
    Process ID:\t\t", proginfo[1], "\n\
    Parent process ID:\t", proginfo[2], "\n\
    Time started:\t\t", proginfo[4]
except:
    print "There was a problem with the program."

このプログラムは、以下のステップに従います。

  1. 確認対象のプロセスの名前を取得して変数に割り当てる (3 行目)。
  2. ps コマンドを実行し、結果をリストに割り当てる (7 行目~ 8 行目)。
  3. プロセスに関する詳細情報を英語で表示する (11 行目~ 16 行目)。

出力結果をリスト 6 に記載します。

リスト 6. 3 番目の例の出力
$ python example3.py
Enter the name of the program to check: xterm

    Full path:          /usr/bin/xterm
    Owner:              knowltoj
    Process ID:         3220
    Parent process ID:  4308
    Time started:       16:51:46

例 4: ユーザー ID とパスワードがポリシーに準拠しているかどうかを確認する

セキュリティーを管理することは、どんなシステム管理者にとっても重要なジョブの一環です。最後のこの例で説明するように、Python によってセキュリティーを管理するジョブは簡単になります。

リスト 7 のプログラムは、pwd モジュールを使ってパスワード・データベースにアクセスし、ユーザー ID (userid) とパスワード (password) がセキュリティー・ポリシーに準拠しているかどうか確認します (この例では、ユーザー ID は最小 6 文字、パスワードは最小 8 文字という設定です)。

ここで、以下の 2 つの注意事項があります。

  • このプログラムは、ユーザーが /etc/passwd に対する完全なアクセス権を持っている場合にのみ有効です。
  • シャドー・パスワードを使用すると、このスクリプトは機能しません (ただし、Python 2.5 にはこのジョブを行う spwd モジュールがあります)。
リスト 7. ユーザー ID とパスワードがセキュリティー・ポリシーに準拠しているかどうかの確認
import pwd

#initialize counters
erroruser = []
errorpass = []

#get password database
passwd_db = pwd.getpwall()

try:
    #check each user and password for validity
    for entry in passwd_db:
        username = entry[0]
        password = entry [1]
        if len(username) < 6:
            erroruser.append(username)
        if len(password) < 8:
            errorpass.append(username)

    #print results to screen
    print "The following users have an invalid userid (less than six characters):"
    for item in erroruser:
        print item
    print "\nThe following users have invalid password(less than eight characters):"
    for item in errorpass:
        print item
except:
    print "There was a problem running the script."

このプログラムは、以下のステップに従います。

  1. カウンター・リストを初期化する (4 行目~ 5 行目)。
  2. パスワード・データベースを開き、データをリストに割り当てる (8 行目)。
  3. ユーザーとパスワードの有効性を確認する (12 行目~ 18 行目)。
  4. 無効なユーザーとパスワードを出力する (21 行目~ 26 行目)。

出力結果をリスト 8 に記載します。

リスト 8. 4 番目の例の出力
$ python example4.py
The following users have an invalid userid (less than six characters):
Guest

The following users have invalid password(less than eight characters):
Guest
johnsmith
joewilson
suejones

スクリプトのその他の用途

Python はさまざまな方法でシステム管理に活用できますが、なかでも特に優れた活用法は、作業を分析し、繰り返し実行している作業を判別し、それらの作業を支援するために Python のモジュールを利用できるかどうかを検討することです (利用できることはほぼ確実です)。

Python を大いに役立てられる具体的な分野としては、以下のものが挙げられます。

  • サービスの管理: 一連のサーバーでの特定アプリケーションのパッチ・レベルを確認し、自動的にパッチを更新する。
  • ロギング: 特定のタイプのエラーが syslog に現れた場合、自動的に E メールを送信する。
  • ネットワーキング: サーバーに Telnet で接続し、接続状況を監視する。
  • Web アプリケーションのテスト: 無料で入手できるツールを使用して Web ブラウザーをエミュレートし、Web アプリケーションの機能とパフォーマンスを検証する。

以上はほんの数例を挙げただけにすぎません。他にもきっと、皆さん独自の有効なアイデアがあるはずです。


まとめ

学習しやすい言語であり、ファイル、プロセス、ストリング、そして数値を処理する優れた能力を持ち、さらに無数のヘルパー・モジュールを備えた Python は、まるでシステム管理者のために作られたようなスクリプト言語です。あらゆるシステム管理者のツールボックスにとって貴重なツールとなります。

参考文献

学ぶために

  • Python Tutorial: このチュートリアルは、基本的な言語情報に関する優れた情報源です。
  • Discover Python」(Robert J. Brunner 著、developerWorks): developerWorks の連載「Discover Python」の一連の記事を読んでください。
  • 公式 Python Web サイト: このサイトには、豊富な情報とダウンロードが用意されています。
  • Python Cookbook: ActiveState が管理するこのサイトは、あらゆるプログラミングをテーマとしてユーザーがスクリプトを貢献するユーザー・コミュニティーです。
  • Planet Python: Python のすべてを網羅したサイトです。
  • 人気のコンテンツ: あなたの同僚がどんな AIX® および UNIX 関連のコンテンツに興味を持っているのかが分かります。
  • AIX and UNIX: developerWorks の AIX and UNIX ゾーンでは、AIX システム管理のあらゆる側面に関する情報、そして UNIX のスキルを向上させる情報を豊富に提供しています。
  • New to AIX and UNIX: このページにアクセスして、AIX と UNIX の詳細を学んでください。
  • AIX Wiki: AIX 関連の技術情報を包括的に集めた環境です。
  • 以下のトピックでAIX and UNIX ライブラリーを検索してください。
  • Safari テクノロジー・ブックストアの Python セクションで、この記事のトピックやその他の技術トピックに関する本を探してください。
  • Safari ブックストア: 特定の技術に関する資料を見つけるには、このオンライン・ライブラリーにアクセスしてください。
  • developerWorks technical events and webcasts: developerWorks technical events and webcasts で最新情報を入手してください。
  • Podcasts: IBM の技術者たちから最新の話題を集めてください。

製品や技術を入手するために

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=AIX and UNIX, Open source
ArticleID=265722
ArticleTitle=システム管理者のための Python
publish-date=09072007