開発環境 C言語(その6)

【連載】

にわか管理者のためのLinux運用入門

【第161回】開発環境 C言語(その6)

[2019/01/16 07:00]後藤大地 ブックマーク ブックマーク

サーバ/ストレージ

実用的なコマンドを作ってみよう

これまで数回に渡り、Linuxカーネルに特有の機能「inotify API」の具体的な使い方を紹介してきた。C言語がわからないと理解しづらい内容だったかもしれないが、カーネルに特有の機能を使うとこういったこともできる、ということは何となく感じてもらえたのではないかと思う。

ここまでだとただの”お勉強”になってしまうのだが、本連載の目的は建設的な努力によって将来発生する仕事を自動的にさばけるようにすることであり、「具体的にこういったことができる」という体験をする必要がある。というわけで今回は、inotify APIを使った具体的なコマンドを紹介しよう。

wait_untilfilechanges.c

例えば、これまで作成してきたC言語のソースコードをコンパイルする方法を考えてみよう。今までの説明であれば、ソースコードを編集したら、その都度ほかのターミナルに移動して、もしくはいったんエディタを終了して、ソースコードをビルド(make)していたと思う。しかし、この処理は決まりきったことであって、できることなら、ソースコードが保存された段階で自動的にビルドしてくれたほうが楽だ。

つまり、次のような繰り返し処理をサクッと書けると、作業がとても簡単になる。

while :
do
    ファイルAが変更されるまで待つ
    ファイルAをコンパイル
done

では、「ファイルAが変更されるまで待つ」を「wait_untilfilechanges」というコマンドにするとしよう。これを「wait_untilfilechanges target_file」のように実行して、「target_file」に書き込みが行われるまで待機するといった処理を行わせたい。つまり、次のような処理が書けるとよいということになる。

while :
do
    wait_untilfilechanges *.c
    make clean
    make
done

上記のように書いておくと、例えばviでソースコードを編集している間に「:w」で書き込みを実施すると、自動的にビルドが実施されたバイナリファイルが更新される、といった動作になる。作業が1つ楽になるわけだ。

この連載はプログラミングを説明するものではないので、ソースコードの書き方は省いて結果を掲載しておく。まず、今回のソースコード用に次のようなMakefileを用意する。

SRCS=   wait_untilfilechanges.c
CMD=    wait_untilfilechanges

OBJS=   ${SRCS:.c=.o}

all: ${OBJS}
    cc -o ${CMD} ${OBJS}

.SUFFIXES: .c .c

.c.o:
    cc -c $<

clean:
    rm -f ${OBJS} ${CMD}

「wait_untilfilechanges.c」の中身は次のようになる。

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/inotify.h>
#include <unistd.h>

int
main(int argc, char* argv[])
{
    int fd;
    int wd[1024];
    char buf[4096], *ptr;
    const struct inotify_event *event;
    ssize_t len;

    /* inotify API にアクセスするためのファイルディスクリプタを生成 */
    fd = inotify_init1(IN_NONBLOCK);

    /* モニタリング対象を追加 */
    for (int i = 1; i < argc; i++)
        /* イベントの種類はIN_MODIFY */
        wd[i] = inotify_add_watch(fd, argv[i], IN_ALL_EVENTS );

    /* モニタリングを実施 */
    for (;;) {
        /* 
         * 複数のイベントをバッファに読み込み
         * ここでイベントが発生するまで処理が待ち状態になる
         */
        len = read(fd, buf, sizeof buf);

        /* 
         * モニタリング対象が変更されていたら処理を終了する
         */
        ptr = buf;
        while (ptr < buf + len) {
            /* バッファにおけるイベントにアクセス */
            event = (const struct inotify_event *) ptr;

            /* イベント種類を確認し該当イベントだったら終了 */
            if (event->mask & (IN_MODIFY | IN_CLOSE)) {
                printf("----\n");
                exit(EXIT_SUCCESS);
            }

            /* バッファにおける次のイベントを指し示す  */
            ptr += sizeof(struct inotify_event) + event->len;
        }
    }

    exit(EXIT_SUCCESS);
}

これまで取り上げてきたソースコードよりも、だいぶシンプルになったことがおわかりいただけるのではないだろうか。wait_untilfilechangesは、「監視対象のファイルやディレクトリが変更されるまで待つ」という処理をするだけのコマンドだ。しかし、これが結構役に立つ。

wait_untilfilechangesの実行サンプル

wait_untilfilechanges.cのコンパイルや実行の例を見てみよう。まず、次のようにコンパイルを実施する。

wait_untilfilechanges.cのコンパイル

ビルドしたコマンドを実行してみよう。wait_untilfilechanges.cファイルを監視して、変更されたらmakeが実行されるという処理を延々と繰り返すというものだ。

ファイルが変更されたらビルドを実施する

次のようにソースコードを変更しながら、適当なタイミングでちょいちょい保存を実行する。

ソースコードを編集しつつ、時々保存する

保存したタイミングで、次のように先ほどwait_untilfilechangesを実行したターミナルではmakeが実行されることを確認できる。

ソースコードが保存されると自動的にmakeが実行される

こんな感じで、inotify APIを使って作成した簡単なコマンドを使うと、日常の作業の自動化ができるわけだ。自分の欲しい機能をコマンドとして実行することで、処理の自動化を進められる。

ここ数回の解説は、C言語を知らないとわかりづらい話だったかもしれない。だが、説明してきたように、多少なりともC言語を使えるとLinuxカーネルの機能を利用できるようになる。身に付けておいて損はしないし、将来楽をするために有用なスキルなので、時間を確保してぜひとも、学習に取り組んでいただければと思う。

※ 本記事は掲載時点の情報であり、最新のものとは異なる場合がございます。予めご了承ください。

一覧はこちら

連載目次

もっと知りたい!こちらもオススメ

なぜ今、統合システムなのか? 押さえておくべき「3つのインパクト」

なぜ今、統合システムなのか? 押さえておくべき「3つのインパクト」

ガートナー ジャパンは10月31日~11月2日、都内で「Gartner Symposium/ITxpo 2017」を開催。11月1日には同社 主席アナリストの青山浩子氏が登壇し「CIOが理解すべき統合システムの3大インパクト」と題する講演を行った。本稿では、講演の内容をダイジェストでお届けする。

関連リンク

この記事に興味を持ったら"いいね!"を Click
Facebook で IT Search+ の人気記事をお届けします

会員登録(無料)

注目の特集/連載
[解説動画] Googleアナリティクス分析&活用講座 - Webサイト改善の正しい考え方
[解説動画] 個人の業務効率化術 - 短時間集中はこうして作る
知りたい! カナコさん 皆で話そうAIのコト
教えてカナコさん! これならわかるAI入門
対話システムをつくろう! Python超入門
Kubernetes入門
AWSで作るクラウドネイティブアプリケーションの基本
PowerShell Core入門
徹底研究! ハイブリッドクラウド
マイナビニュース スペシャルセミナー 講演レポート/当日講演資料 まとめ
セキュリティアワード特設ページ

一覧はこちら

今注目のIT用語の意味を事典でチェック!

一覧はこちら

ページの先頭に戻る