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

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

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

4月から新入社員さんが入ってこられ、早速研修が行われています。

わたしも、5月に某プログラミング言語を教えることになっているのですが、 先日、別の研修のお手伝いをちょろっとだけ行いました。

ちょうど演習をやっていて、徘徊して質問に答えるチューター的な役割を担いました。 その際思ったのは、コマンドラインでの作業が、想定以上にぎこちなく、 あやういということでした。

よく考えますと、わたしなんかは、 BASICインタプリタが動作する8ビットなマイコン(パソコン)に始まり、 その後のMS-DOS(Windowsはまだ3.0とかでした)や商用なUNIXなど、 いずれもコマンドライン前提のものをずっと使っていました。

ですが、いまの若いひとたちは、WindowsもMac OS Xも、はたまた Linuxも、 GUIが前提となっています。いずれも、 コマンドラインを使わず大半の操作ができてしまい…もとい、できるようになっています。

育ってきた環境を考慮した研修内容にすべきなのではないか、という気がしつつ、 甘くすることがよいわけでもないという気もしつつ、考えの整理がつかないまま、 5月の講師に投入してしまいそうです。

まずは、お互いに経験して失敗してみることも必要かな…ということで、 今回もはりきってまいります。

今回のお題 - awk を少しかじってみる

日々、様々なOSS(オープンソースソフトウェア)が開発され、 われわれを取り巻く環境は目まぐるしく変化しています。

サーバ上でちょろっと仕込むものも、かつてはシェルスクリプトで書いていたのが、 Perl や Python や PHP などで書くようになってきた…のかもしれません。 (すみません、私自身はPerl止まりです。)

ここ数年で構築された新しいサーバなんかは、 そういう方針でもいいように思います。
ですが、古くからあるサーバや、 古いサービスをそのまま移行して動作をさせている場合は、 いわゆるレガシーなもので構成されていることが多いように思います。

その中でも、遭遇して戸惑うのが、AWK(Aho Weinberger Kernighan)ではないでしょうか。 3人の開発者の頭文字から命名された awk は、 grep や sed コマンドほど有名ではありませんが、 テキストを処理してあれこれするには便利なコマンドでした。(…あ、過去形…。)

というわけで今回は、awk のさわりをご紹介したいと思います。
いまどき awk なんて使わないよとお考えの貴兄も、 いつかどこかで役に立つかもと思って、さらっと目を通していただけますと幸いです。

awk の基本的な動きをさらっと

awk は、テキストの処理を主な目的とするスクリプト言語です。

具体的には、引数に指定されたテキストファイルか標準入力から1行ずつ読み込み、 その行があるパターンにマッチしたとき、対応するアクションを実行します。

パターンとアクションの羅列をスクリプトとして記述します。 スクリプトは引数に直接指定できますし、 ファイルに記述してそのファイルを引数に指定することもできます。
どちらにしても、書式は以下の通りです。

  パターン { アクション }

パターンには、主に以下のようなものを指定できます。

パターン概要
/正規表現/指定した正規表現にマッチしたら実行
BEGIN最初に必ず実行
END最後に必ず実行
パターン && パターンいずれのパターンにもマッチしたら実行
パターン || パターンいずれかのパターンにマッチしたら実行
パターン, パターン指定したパターンの間の行に対して実行
! パターンパターンにマッチしなかったら実行
(省略)すべての行に対して実行

「BEGIN」と「END」は特別な意味を持ちます。BEGINは処理を開始する前に、 ENDは処理を完了した後に実行します。
また、パターンは省略可能で、省略した場合はすべての行がマッチすると判断されます。

アクションには、様々なことを指定できます。上記のようにまとめるのが難しいため、 以降で具体的な例を示します。

まずは超シンプルな例から

細かいことは後回しにして、早速動かしてみましょう。
最初は超勘単に、入力をそのまま出力してみます。以下では、 /etc/hostsをそのまま出力しています。

  $ awk '{ print }' /etc/hosts
  127.0.0.1      localhost.localdomain localhost
  ::1            localhost ip6-localhost ip6-loopack

  # home network
  192.168.1.25   vista     # Windows Vista
  192.168.1.184  fedora16  # Fedora16 on VirtualBox
  ...

「print」というステートメントは、その名の通り、出力するためのものです。 引数を省略すると、入力した行そのものを出力します。
入力した行は「$0」で表されるため、以下のように実行しても同じ結果が得られます。

  $ awk '{ print $0 }' /etc/hosts

各行のうち、スペースで区切られたデータ(フィールド)は、 「$1」「$2」…で参照できます。ですので、 たとえば /etc/hosts のIPアドレス部分を出力するなら、以下のように実行します。

  $ awk '{ print $1 }' /etc/hosts
  127.0.0.1
  ::1

  #
  192.168.1.25
  192.168.1.184
  ...

…おっと、IPアドレスじゃないものも含まれていますね。
先頭が「#」じゃないやつだけに絞ってみましょう。

  $ awk '/^[^#]/ { print $1 }' /etc/hosts
  127.0.0.1
  ::1
  192.168.1.25
  192.168.1.184
  ...

IPアドレスだけ出力されるようになりました。

ちなみに、最初のホスト名だけ出力するには、以下のように実行します。

  $ awk '/^[^#]/ { print $2 }' /etc/hosts
  localhost.localdomain
  localhost
  vista
  fedora16
  ...

ちょっと実用的っぽい例

次に、duコマンドでディスク使用量を確認したら、最後に合計を出力してみましょう。

  $ du -sk *
  100     2001
  5520    2002
  6160    2003
  ...
  6756    2011

素の du だと、上記のように、それぞれの結果だけ出力されます。

で、いきなり答えを書くと、こうなります。

  $ du -sk * | awk 'BEGIN { total = 0 } \
  { print; total += $1 } \
  END { print total }'
  100     2001
  5520    2002
  6160    2003
  ...
  6756    2011
  68048

最初に、変数 total に 0 を代入して初期化します。
次に、各行に対して、print で出力しつつ、 第1フィールドの数値をtotalに加算します。
最後に、集計したtotalの値を出力します。

やや見づらいですので、スクリプトを別ファイルにしてしまいましょう。

BEGIN { total = 0 }
      { print; total += $1 }
END   { print total }

これを、dusum.awk というファイル名で保存したとしますと、以下のように、 「-f」オプションでそのスクリプトファイルを指定して実行します。

  $ du -sk * | awk -f dusum.awk

ちなみに、変数は 0 で初期化されるため、BEGIN の行は省略可能です。

    { print; total += $1 }
END { print total }

さらにちなみに、こうすると、単体で動作するようになります。

#!/usr/bin/awk -f
    { print; total += $1 }
END { print total }

先ほどと同じファイル名だとすると、これに実行権をつけて実行すれば、 同じ結果が得られます。

  $ chmod +x dusum.awk
  $ du -sk * | ./dusum.awk

もうちょっと複雑な例

最初にあった、/etc/hosts からホスト名を抜き出す例ですが、 ちゃんと全部のホスト名を抜き出すようにしてみます。

#!/usr/bin/awk -f
/^[^#]/ {
    printf("%s:", $1);
    for(i=2; i<=NF; i++) {
        if($i ~ /#/) {
            break;
        } else {
            printf(" %s", $i);
        }
    }
    print ""
}

最初に、「printf」ステートメントでIPアドレスを出力します。
次に、2つ目以降のフィールドをfor文で確認します。「NF」はフィールド数です。 フィールドに「#」が含まれていればそれ以降は解釈せず、 そうでなければ出力します。
…というのを延々と繰り返しています。

これを、gethost.awk というファイル名で保存したとしますと、 実行権をつけて以下のように実行します。

  $ chmod +x gethost.awk
  $ ./gethost.awk < /etc/hosts
  127.0.0.1: localhost.localdomain localhost
  ::1: localhost ip6-localhost ip6-loopack
  192.168.1.25: vista
  192.168.1.184: fedora16
  ...

IPアドレスの後に、ずらずらっとホスト名が並びます。
ちゃんと、コメント部分が取り除かれていることがわかります。

おわりに

以上、awk の入門編的な内容をお送りしました。

アクションのところの書き方が難しい(情報が少ない)かもしれませんが、 検索すればそれなりに有用な情報が得られますので、後は、 試行錯誤して動作するところまで持っていけばよいのではないかと思います。

次回を、awk の続きにするか、まったく違う内容にしてしまうか、 迷っております。よろしければお気軽にご意見をくださいませ。

宿題の答え

前回の宿題は、

カレントディレクトリ以下で、1週間以上前に修正された、ファイル名 が「backup」で始まるファイルをすべて削除してください。

でした。

「1週間以上前に修正された」という条件は、 「6日より前」に修正されたということなので、「-mtime +6」と表せます。
また、ファイル名が「backup」で始まるというのは、 「-name backup\*」で表せます。
複数の条件がすべて該当する場合のみ実行するには、条件を羅列するか、 「-a」もしくは「-and」オプションで条件をつなぎます。
そして、最後の削除は「-delete」です。

これらを踏まえた結果が、以下のようになります。

  $ find . -mtime +6 -name backup\* -delete

もしくは、以下のいずれかでも構いません。

  $ find . -mtime +6 -a -name backup\* -delete
  $ find . -mtime +6 -and -name backup\* -delete
  $ find . -mtime +6 -name backup\* -exec rm -f {} \;
  ...以下略...

ちなみに、「-o」もしくは「-or」で条件をつなぐと、 条件のいずれかに該当したら実行します。

とりあえず、最後の -delete を外して表示だけさせてみて、 試行錯誤を繰り替えしてくださいませ。

今回の宿題

今回の宿題は、

  du -sk * の結果のうち、1MB以上のものだけを出力しましょう。

です。

1MB に限らず、 ある一定以上のサイズのディレクトリに対して何か対策を施す必要がある、 というシチュエーションは十分あり得るのではないかと思います。

というわけで、試行錯誤してみてください。

あとがき

4月からは、新人さんを意識して、初心的な内容を取り上げております。

今、日経Linuxで連載している「WindowsからLinux完全移行 超入門」も、 Windowsユーザの方を対象に、Linuxの移行と言いますか、 使い方を簡単に説明させていただいています。

Windowsユーザの方々に、ということになっていますが、 結局のところはLinux初心者の方を対象にしているといってもよいと思います。
というわけで、4月という季節もあってか、 初心者の方々を意識する日々が続いている感じです。

でもって、5月8日に発売される6月号では、コマンドラインを取り上げる予定です。 今回の内容がさっぱりわからんかったという貴兄は、 まずこのあたりから手をつけるとよろしいのではないでしょうか。

日経Linux
http://itpro.nikkeibp.co.jp/linux/

とはいえ、これのためだけに1490円払ってとは口が割けても申しません。 まずは本屋さんで立ち読んでみてください。
(でも、もし万が一購入されましたら、 アンケートによかったとか書いていただけますと幸いです。:-p)

あ、コマンドラインといえば、 いつも最後に載っている「シス管系女子」というマンガでは、 もっとわかりやすく楽しい感じで、 コマンドラインの使い方を説明してくださっています。 こちらもぜひ読んでみてください。
(そのうち単行本化とかされればよいと思うのですが。)

 

あ、宣伝だけであとがきが終わってしまいました…スミマセン…。

 

今回も、ここまで読んでいただき、たいへんありがとうございました。
次回は、5月6日(日) の未明にお会いしましょう!

 

「いますぐ実践! 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://usupi.org/k/ (モバイル栗日記)


[バックナンバーのトップへ] [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

▼ せんでん




▼ 最近読んだ本

▼ 気に入ってる本