月別アーカイブ: 2015年10月

Ubuntu 14.04 で SystemTap 2.9 を使う

Ubuntu 14.04 で DTRACE に近い機能を実現する SystemTap を使うための方法。

いくつか参考になる情報があるけど、どうもうまくいかない。

Ubuntu 14.04 (trusty) のリポジトリの SystemTap のバージョンは 2.3 で、これが古くてアップデートされたカーネル(自分の場合は 3.16.0-50)に対応していないのではないかと予想。SystemTap 公式を参考にして最新版をインストールしたところ、使えるようになった。

  1. 必要なパッケージのインストール
    $ sudo apt-get install gcc g++ elfutils libdw-dev
  2. カーネルの dbgsym のインストール
    • ddebs リポジトリの追加
      $ codename=$(lsb_release -c | awk '{print $2}')
      $ sudo tee /etc/apt/sources.list.d/ddebs.list << EOF
      deb http://ddebs.ubuntu.com/ ${codename} main restricted universe multiverse
      deb http://ddebs.ubuntu.com/ ${codename}-security main restricted universe multiverse
      deb http://ddebs.ubuntu.com/ ${codename}-updates main restricted universe multiverse
      deb http://ddebs.ubuntu.com/ ${codename}-proposed main restricted universe multiverse
      EOF
      $ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys ECDCAD72428D7C01
      $ sudo apt-get update
    • カーネルの dbgsym パッケージのインストール
      $ sudo apt-get install linux-image-$(uname -r)-dbgsym
  3. SystemTap の入手・インストール
    • 公式の情報
    • リリース版置き場
    • SystemTap の入手
      $ wget https://sourceware.org/systemtap/ftp/releases/systemtap-2.9.tar.gz
    • SystemTap のコンパイル
      $ tar xvfz systemtap-2.9.tar.gz
      $ cd systemtap-2.9
      $ ./configure
      $ make
    • SystemTap のインストール
      $ sudo make install
  4. SystemTap の動作確認
    以下のようになれば OK

    $ sudo stap -e 'probe begin { println("Hello, World!") exit() }'
    Hello, World!

Top で特定のユーザのプロセスを非表示にする

top でプロセスの一覧を眺めている時に root のプロセスが邪魔な時がある。そんな時には以下の方法で特定のユーザのプロセスを非表示にできる。

$ top -U !username

top コマンド起動後に u を押して !username と入力することでも可能。

参考:How to exclude some users from Linux Top screen?

Time Machine で 別のモデルのバックアップからリストアするのは要注意?

13-inch MBP (late 2011) で作った Time Machine のバックアップから、Mac mini (late 2014) へリストアして使っていたのだが、どうにもパフォーマンスが悪い。Chrome で幾つかタブを開いている状態で、さらに新しいタブを開く操作 (⌘-t) を押すと開くまでに数秒かかるなど、ストレスのある状況が続いていた。

ダメ元で一度再セットアップしてみようと思い、Yosemite をインストールしなおしたところ、これまでの症状が嘘のように改善。Mac は Time Machine による移行が簡単なところが売りなんだと思っていたけど、パフォーマンスに関してはやっぱり再セットアップしたほうがいいらしい。

/var/spool/mail/ に届いたメールを処理する方法

概要

cron で処理した結果がメールで送られてくるときに /var/spool/mail/username に届く。mbox 形式で書き込まれて、これは mailx で読んだり消したりできる。だけど、mailx は対話式のプログラムで自動で中身を見て処理したりできない。

メールの数が大量になると(例えば毎分スクリプトを回してたりすると)チェック不能になるし、かといってメールを送らないようにするのはちょっと・・・みたいな時に使えます。

procmail とかで受信時に処理するという手もあると思うけど、今回はまとめてバッチ処理する方法を探してみた。

動作環境は CentOS 7 + Python 2.7。

大雑把な手順

  1. GNU Mailutils の movemail で /var/spool/mail/username を別のディレクトリ(ホームディレクトリ)に移動
    • /var/spool/mail/ はユーザ権限で新しいファイルを作れないので、mbox ファイルを編集するときにロックが取れないという問題があるので、予めメールを移動
  2. mbox を解釈できるライブラリ等を使って mail を解釈して処理
    • 使えるツールはいろいろあると思うが今回は python を使用
    • cron から送られてくるメールに対してテストケースを書いて特定の条件(エラー等)を満たすメールだけを残す、とか特定のファイルに書き出す、とかの使い方を想定

GNU Mailutils のインストール

CentOS のリポジトリにはなさそうだったので公式サイトからダウンロードしてコンパイル・インストール。configure -> make -> make install のいつもの流れで OK。

メール処理スクリプトの例

  • $MAIL が設定されていることを前提(/var/spool/mail/username とかになっているはず)
  • $HOME/mail/INBOX をメールの移動先とした(予め $HOME/mail を作っておく)
  • GNU Mailutils のツールにはパスを通しておく
  • このままは動かないのでご注意
#!/usr/bin/env python

import os
import subprocess
import mailbox

def chkMsg(msg):
    subject = msg["subject"]
    body = msg.get_payload()

    # メッセージの内容によって返り値を変える
    if 削除:
        return 0
    else:
        return 1

mboxpath = os.environ["HOME"] + "/mail/INBOX"
subprocess.call(["movemail", os.environ["MAIL"], mboxpath])

mbox = mailbox.mbox(mboxpath)
to_remove = []
for key, msg in mbox.iteritems():
    if chkMsg(msg) == 0:
        print "Removing: ", key
        to_remove.append(key)

mbox.lock()
try:
    for key in to_remove:
        mbox.remove(key)
finally:
    mbox.flush()
    mbox.close()

subprocess.call(["mail", "-f", mboxpath])

参考

スクリプト言語で環境変数を取得する方法

シェルスクリプト(Bash)

普通の変数と同様に参照すれば良い。

変数が設定されているかどうかの確認:

[ -z "${HOGE+x}" ]

変数の取得:

echo $SHELL

Python

準備:

import os

変数が設定されているかどうかの確認:

os.environ.has_key("SHELL")

変数の取得:

os.environ["SHELL"]

R

変数が設定されているかどうかの確認:

Sys.getenv("SHELL") が "" かどうかをチェックする。

変数の取得:

Sys.getenv("SHELL")

R で igraph を使うための Tips

graph 構造を持つデータの処理をしたくて、R + igraph を使おうと思ったけど、一部ハマったことがあるのでメモ。

igraph は Ubuntu では標準のリポジトリにはないので、R の中で、

install.packages("igraph") 

してインストールする。すると igraph の最新版が入るわけだけど、読み込んで使おうとするとなんか変なエラーで止まってしまう。igraph のページに明示的には書かれていないけど、 Ubuntu でデフォルトのリポジトリで入れられる R のバージョンは古いらしい。

そこで、CRAN が提供している Ubuntu 向けのリポジトリを apt-get の source に追加して、apt-get で R を最新版にアップデートすると無事に使えるようになる。

ちなみに、R でパッケージをインストールする際には、一般ユーザで install.packages() を実行すると、ユーザディレクトリの中にインストールされ、特権ユーザで実行するとシステムにインストールすることができる。