GDM使用時にlibnotifyのnotify-sendがcronから動作しない件とその対処(バージョン2.30系時点)
以前はGDMからグラフィカルログインしたときにも環境変数DISPLAYの指定のみでcronからlibnotifyのnotify-sendコマンドによる通知が行えていたのだが、その後のバージョン(2.30系時点)ではうまく通知が表示されず、X Window System上で動作する他のGUIプログラムも同様に起動できない。
cronで実行するコマンド行をいじってファイルにメッセージを書き出すようにしてそれを見てみると
libnotify-Message: Unable to get session bus: /usr/bin/dbus-launch terminated abnormally with the following error: No protocol specified Autolaunch error: X11 initialization failed.
のようになっていた(状態によって微妙に出力内容が変わる場合がある)。
詳細
色々と調べたところ、GDMからログインしたときには- Xの認証に${HOME}/.Xauthorityは用いられない
- 環境変数XAUTHORITYに示した場所のファイルが代わりに用いられる
という動作になっており、他のディスプレイマネージャ(ログイン画面のプログラム)からログインした場合とXの認証の動作に違いがあることが分かった。
環境変数XAUTHORITYはGDMからログインしたセッションの中から起動されるプロセスでは設定されているが、cronで実行される際には設定されていない。
そのファイルの場所は
/var/run/gdm/auth-for-[ユーザ名]-[文字列]/database
となっているのだが、文字列部分はランダムで、かつ、ディレクトリ/var/run/gdm/は
$ stat -c "%A %U" /var/run/gdm/ drwx--x--x root
(ディストリによるかもしれないが)管理者(root)だけしか一覧を取得できず、パターンに合ったものを探索するという方法を用いずに直接正確なパスを得てこれを指定するということが必要になる。
対処
手っ取り早い方法として- グラフィカルログイン時の自動起動スクリプトの中でDISPLAYとXAUTHORITYの2つの環境変数をファイルに書き出す
- cronからはそのファイルをもとにして環境変数を設定しつつコマンドを実行するようにする
のようにしてみることにする。
デスクトップ環境などの自動起動スクリプトの中に
env | egrep "^(DISPLAY|XAUTHORITY)=" | while read l; do echo "export ${l}" done >| ~/auth.sh chmod 600 ~/auth.sh
のように記述すると、次回のログイン時に
export DISPLAY=:0 export XAUTHORITY=/var/run/gdm/auth-for-[ユーザ名]-[文字列]/database
といった内容のシェルスクリプトが${HOME}/auth.shという場所にできるので、cronからは
[分] [時] [日] [月] [曜日] sh -c '. ~/auth.sh; notify-send [タイトル] [本文]'
のように実行すると通知が表示されるようになる。シェルスクリプトを記述してそれをcronで実行したい場合の内容は
#! /bin/sh . ~/auth.sh notify-send [タイトル] [本文]
のようになる。
使用したバージョン:
- GDM 2.30.2
- libnotify 0.4.5
- cronie 1.4.4