Linuxで定期的にプログラムを動かす時にはcronと呼ばれる仕組みを使う。また、デスクトップ上に通知バルーンを出すには`notify-send
`というコマンドが使える。これらを組み合わせれば、画面上に定期的に通知を出せる筈だ。
ところが、コレがなかなか上手く行かない。 `crontab -e
` で直接`notify-send
`を指定しても、`notify-send
`を呼び出すシェルスクリプトを指定してもダメ。調べてみると、単純に`notify-send
`を使うだけではダメなようだ。cronで呼び出されるプログラムは、古き良きCUIプログラムである事が前提で云々。
ググると何通りかの回避策が出てくる。が、試した幾つかは上手く行かなかった。もしかしたら同じように悩んでいる人が居るかもしれないし、以下に纏める。
上手く行った方法:cronで呼ばれるスクリプト内で環境変数DBUS_SESSION_BUS_ADDRESSを設定する
webの知見は「重要な事は先に書け」と言っているので、当記事はそれに従い、上手く行った方法を始めに挙げようと思う。忙しい人は此処だけ読めば後は無視して構わない(多分)。
「shell - Using notify-send with cron - Unix & Linux Stack Exchange」で一番voteされている回答の方法。即ち、WM起動時に環境変数をセットするスクリプトファイルを生成し、cronで実行するスクリプト内で、生成したスクリプトファイルを実行する方式。
環境変数設定用スクリプトを生成するスクリプトが以下。WM起動後に自動的に実行する仕組みが在れば、それで自動実行すれば良いのだろう:
#!/bin/sh
touch $HOME/.dbus/Xdbus
chmod 600 $HOME/.dbus/Xdbus
env | grep DBUS_SESSION_BUS_ADDRESS > $HOME/.dbus/Xdbus
echo 'export DBUS_SESSION_BUS_ADDRESS' >> $HOME/.dbus/Xdbus
exit 0
cronで実行するスクリプトの最初の方で、それを実行する:
if [ -r "$HOME/.dbus/Xdbus" ]; then
. "$HOME/.dbus/Xdbus"
fi
恐らく、大体のWMで使える方法だと思われる。ファイルが1つ生成される事が難点かも。
上手く行かなかった方法:cronで呼ばれるスクリプト内で環境変数DBUS_SESSION_BUS_ADDRESSを設定する
やろうとしている事自体は、前述の上手く行った方法と同じ。ただし、此方はスクリプトファイルを生成しない。
「cron - Notify-send doesn't work from crontab - Ask Ubuntu」の回答で挙げられている方法。cronでの実行時に以下のスクリプトを実行、環境変数の内容を取得し、cron環境用に設定し直す。
eval "export $(egrep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep -u $LOGNAME gnome-session)/environ)";
条件は、(スクリプトの内容から明らかだが)セッションマネージャとして`gnome-session
`を用いている事。あと恐らくWMもGNOMEを使っている事。少なくとも、Awesome WMでは上手く行かなかった (`pgrep -u $LOGNAME gnome-session
` が何も返さなかった)。GNOMEでは上手く行くのは確認できた。「GNOME一筋です!」って人なら、余計なファイルも生成されないし、此方の方が合っているかもしれない。
上手く行かなかった方法:cron環境下で、環境変数DISPLAYを設定する
割と頻繁に見つかる方法。そして一番手軽。だが私の環境では動かなかった。
DISPLAYを設定するのも、 `crontab -e
` した時の頭の方の行だとか、各設定のコマンドの頭で設定しろだとか、呼び出すスクリプト内部で設定しろだとか多岐に渡る。その値も「:0
」だったり「:0.0
」だったり。でも動かなかった。
いやもう、上手く行く方法を見つけるのに意外と時間がかかった。
cronで`notify-send
`が使えないって事は、他のGUIプログラムも無理なんだろうか。無理なんだろうな。