cronでnotify-sendを使用する


32

KDE / Awesome WMでArch Linuxを使用しています。notify-send一緒に仕事をしようとし ていcronます。

DISPLAY/ XAUTHORITY変数を設定notify-sendし、「sudo -u」で実行しようとしましたが、すべて結果はありませんでした。

セッションからnotify-sendをインタラクティブに呼び出して通知を受け取ることができます。

FWIW、cronジョブは正常に実行されていますが、一時ファイルに内容をエコーし​​て確認しました。動作に失敗するのは「通知送信」だけです。

コード:

[matrix@morpheus ~]$ crontab -l
* * * * *  /home/matrix/scripts/notify.sh

[matrix@morpheus ~]$ cat /home/matrix/scripts/notify.sh
#!/bin/bash
export DISPLAY=127.0.0.1:0.0
export XAUTHORITY=/home/matrix/.Xauthority
echo "testing cron" >/tmp/crontest
sudo -u matrix /usr/bin/notify-send "hello"
echo "now tested notify-send" >>/tmp/crontest

[matrix@morpheus ~]$ cat /tmp/crontest
testing cron
now tested notify-send

[matrix@morpheus ~]$ 

通知送信が機能する前と後のエコーを見ることができます。
また、私は設定しようとしましたDISPLAY=:0.0

更新:もう少し検索すると、DBUS_SESSION_BUS_ADDRESSを設定する必要があることがわかりました。そして、インタラクティブセッションから取得した値を使用してこれをハードコーディングした後、小さな「hello」メッセージが毎分画面にポップアップし始めました。

しかし、キャッチはこの変数がこの投稿ごとに永続的ではないため、そこで提案されている名前付きパイプソリューションを試してみます。

[matrix@morpheus ~]$ cat scripts/notify.sh
#!/bin/bash
export DISPLAY=127.0.0.1:0.0
export XAUTHORITY=/home/matrix/.Xauthority
export DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-BouFPQKgqg,guid=64b483d7678f2196e780849752e67d3c
echo "testing cron" >/tmp/crontest
/usr/bin/notify-send "hello"
echo "now tested notify-send" >>/tmp/crontest

cron(少なくとも直接ではなく)notify-sendをサポートしていないように思えるので、もっとcron使いやすい他の通知システムがありますか?


これは私が見る限り機能するはずです。&>>/tmp/crontest通知送信行にを追加して、notify-sendエラーメッセージが表示されるかどうかを確認してください。
グレアム14年

好奇心から、あなたは私の解決策を試しましたか?それははるかに単純で、私のDebianで完全に機能しているように見えます。私が知っているだけで求めているならば、それはDebian固有のか
terdon

@terdon私はあなたの解決策を試してみました(簡単なテストです)、それは私のDebianシステムで動作するようです。本当に簡単なので、一般的に適用できるかどうか知りたいです。
マルコ14年

@Marco私はLMDE(本質的にはDebianテスト)に参加しており、CinnamonをDEとして使用しています。それらを超えて機能するかどうかはわかりません。
テルドン

@Marco&terdon:Ubuntuの人はそうすることができます:ubuntuforums.org/showthread.php
t=

回答:


29

DBUS_SESSION_BUS_ADDRESS変数を設定する必要があります。デフォルトでは、cronは変数にアクセスできません。これを修正するには、次のスクリプトをどこかに置き、ユーザーがログインしたときに、たとえばawesomerun_oncewikiに記載されている機能を使用して、それを呼び出します。関数が必要以上に頻繁に呼び出されても害はないため、どのメソッドでも実行できます。

#!/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

これにより、必要なDbus環境変数を含むファイルが作成されます。次に、cronによって呼び出されるスクリプトで、スクリプトをソースとして変数をインポートします。

if [ -r "$HOME/.dbus/Xdbus" ]; then
  . "$HOME/.dbus/Xdbus"
fi

同じメカニズムを使用する回答を次に示します。


1
私は解決策にほとんど近づいたことを見てうれしいです。マルコ、ありがとう!
justsomeone

素晴らしい、私はあなたの答えを再利用し、ここにいくつかの詳細な手順を追加しました:askubuntu.com/a/537721/34298
rubo77

これはセキュリティ上のリスクではないでしょうか?security.stackexchange.com/questions/71019/...
rubo77


私はubuntu 15.10でDBUSを含まない他の多くの答えを試しましたが、何も機能しませんでした。これはシンプルで完璧に機能します。
バスティア

16

crontab自体で変数を設定する必要があります。

DISPLAY=:0.0
XAUTHORITY=/home/matrix/.Xauthority

# m h  dom mon dow   command 
* * * * *  /usr/bin/notify-send "hello"

sudo少なくとも私のシステムには必要ありません。


お時間をいただきありがとうございます。これは簡単な解決策のようです。残念ながら、これは私にとっては
うまくいき

@justsomeoneハァッ、オーケー、デスクトップ環境に依存するかもしれません。
テルドン

これは、ディストリビューションまたはデスクトップ環境と関係があると思います。Ubuntuユーザーにとっては、私がオンラインフォーラムで見たものから、簡単な解決策がうまくいくようです。
justsomeone 14年

@justsomeone私はDEとしてCinnamonを使用しているDebian(LMDE)にいます。Xの起動方法、またはDEが使用する通知システム、dunnoに何らかの関係がある可能性があります。
テルドン

Ubuntu 14.04 / 14.10で動作することを確認しました。GNOMEとUnityを使用。
ジョードンベッドウェル14

8

Xセッションに関連する環境変数を取得する最も安全な方法は、Xにログオンしているユーザーのプロセスの環境から取得することです。私にとってDebianの問題だと思われます):

X=Xorg                   # works for the given X command
copy_envs="DISPLAY XAUTHORITY DBUS_SESSION_BUS_ADDRESS"

tty=$(ps h -o tty -C $X | head -1)
[ -z "$tty" ] && exit 1

# calling who with LANG empty ensures a consistent date format
who_line=$(LANG= who -u | grep "^[^ ]\+[ ]\+$tty")

x_user=$(echo $who_line | cut -d ' ' -f 1)  # the user associated with the tty
pid=$(echo $who_line | cut -d ' ' -f 7)     # the user's logon process

for env_name in $copy_envs
do
  # if the variable is not set in the process environment, ensure it does not remain exported here
  unset "$env_name"

  # use the same line as is in the environ file to export the variable
  export "$(grep -az "^$env_name=" /proc/$pid/environ)" >/dev/null
done

sudo -u "$x_user" notify-send "hello"

これは、見つかった最初のXユーザーにメッセージを送信しますが、ループを追加してすべてのユーザーに送信することもできます。

更新

utmp形式を更新すると、who2列目にttyではなくディスプレイが表示されるようです。これは実際に物事を簡単にします。以前は最後にコメントの表示のみを印刷していたので、元の答えを当てにするのは安全ではないと判断しました。この場合、これを試してください:

X=Xorg                   # works for the given X command
copy_envs="DISPLAY XAUTHORITY DBUS_SESSION_BUS_ADDRESS"

# calling who with LANG empty ensures a consistent date format
who_line=$(LANG= who -u | awk '$2 ~ ":[0-9]"')

x_user=$(echo $who_line | cut -d ' ' -f 1)  # the user associated with the tty
pid=$(echo $who_line | cut -d ' ' -f 7)     # the user's logon process

for env_name in $copy_envs
do
  # if the variable is not set in the process environment, ensure it does not remain exported here
  unset "$env_name"

  # use the same line as is in the environ file to export the variable
  export "$(grep -az "^$env_name=" /proc/$pid/environ)" >/dev/null
done

sudo -u "$x_user" notify-send "hello"

who_lineコマンドにはttyが印刷されていないため、Trustyではこれは機能しません。出力は次のようになりme :0 2015-09-23 10:40 ? 17234ます。
ブルージェイ

1
@blujay、更新。
グレアム

おかげで、それは動作します。ただし、別の回答で投稿したように、さらに簡単な解決策があります。
ブルージェイ

@blujayええ、これはポータブルな回答の試みでした。ただし、これが本当に可能かどうかはわかりませんが、ほとんどの場合はまだ機能するはずです。
グレアム

2

このワンライナーは、クローニーと一緒にマンジャロで働いていました。

# Note: "1000" would be your user id, the output of... "id -u <username>" 
10 * * * * pj DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus notify-send 'Hello world!' 'This is an example notification.'

非常にいDBUS_blah_blahがないと、まったく機能しません。私もjournalctl -xb -u cronie役に立ちました。私はまだCronieに精通していませんが、「crontab」を作成しました。/etc/cron.d/mycronjobsそのファイル名が必要かどうか、またはcron.dディレクトリ内のすべてを読み取るかどうかはわかりません。

ここで解決策を見つけましたhttps://wiki.archlinux.org/index.php/Desktop_notifications


2

Ubuntu 18.04でi3を使用しています。これを解決する私の方法は次のとおりです。

* * * * * XDG_RUNTIME_DIR=/run/user/$(id -u) notify-send Hey "this is dog!"


1

Ubuntu Trustyのcronjobでnotify-sendを機能させるにはこれで十分です。

#!/bin/bash
export DISPLAY=$(who -u | awk  '/\s:[0-9]\s/ {print $2}')

DISPLAYcronjobを実行しているユーザーのを単にエクスポートします。それは設定XAUTHORITYまたはなしで私のために動作しますDBUS_SESSION_BUS_ADDRESS


1
Ubuntu 16.04でも動作します。実際に、cronがPerlスクリプトを起動しています。このsystem()はbashスクリプトで、別のPerlスクリプトを起動し、system( "notify-send ...")を実行します。エクスポートコマンドをbashスクリプトに追加すると、そのスクリプトの環境が変更され、最後のPerlスクリプトが継承して、システムで使用できるようになりました( "notify-send ...")。ブルージェイを見つけてください!
ティム

1

Pythonパッケージを快適にインストールできるLinuxをお使いの方のために、私はうまく機能しているnotify-send-headlessプログラムをリリースしました。/proc必要なユーザー名と環境変数を検索し、notify-sendこれらの変数で実行します(sudo必要に応じて、必要なユーザーに切り替えるために使用します)。


1

スクリプトを作成することもできます。

#!/usr/bin/env bash
runuser -l [yourusername] -c 'DISPLAY=:0 notify-send "hey there user"'

次に、で実行しsudoます。ただし、crontab -eコマンドを作成したユーザーですべてのコマンドを実行するため、次のコマンドを使用せずに呼び出すと十分ですsudo

#!/usr/bin/env bash
DISPLAY=:0 notify-send "hey there user"

少なくとも私にとってはそうです。それはすべて環境設定に依存しているようです。


0

このスクリプトをcronで使用して、MPDを1時間ごとにtwitterで再生するように投稿します

#!/bin/bash
export DISPLAY=":0.0"
msg=$(mpc current -h 192.168.1.33)
twitter set "#MPD Server nowplaying $msg :  http://cirrus.turtil.net:9001"
#ttytter -status="#MPD Server nowplaying $msg. http://cirrus.turtil.net:9001"

exit 

notify-sendを使用した同様のスクリプト

#!/bin/bash
export DISPLAY=":0.0"
notify-send -i ~/.icons/48arch.png 'OS- Archlinux x86_64 : DWM Window Manager' 'Installed on Sun Apr 21 2013 at 18:17:22' 
exit

KDEが独自の通知デーモンIIRCを使用しているため、問題が発生している可能性があります。


0

その価値のために....

これを機能させるには、Debian Jessieで次のすべてを使用する必要がありました...

export DISPLAY=:0.0
export HOME=/home/$user
source "$HOME/.dbus/session-bus/*-0"

これらのいずれかを除外すると、動作が停止しました。


文字通り呼ばれる何のファイルは存在しませんので、ここに書かれたように、その最後の行には何もしません*-0、あなたにsession-busディレクトリ。意味するかもしれないsource "$HOME"/.dbus/session-bus/*-0
ロアイマ

0

sudoを使用:

sudo -u $currentxuser notify-send $message

ヒント:

このコマンドで現在のxユーザーを取得できます

ps auxw | grep -i screen | grep -v grep | cut -f 1 -d ' '

加えて...

currentxuser=$(ps auxw | grep -i screen | grep -v grep | cut -f 1 -d ' ')
echo $currentxuser

知っておきたいこと:

ルートの下で実行されているCronはxにアクセスできないため、すべてのGUIコマンドは表示されません。1つの簡単な解決策は、このコマンドで現在のxユーザーの承認されたxユーザーにルートを追加することです

xユーザーシェルから

xhost local:root

または

sudo -u $currentxuser xhost local:root

-1

Graemeが提供したものよりも簡単なスクリプトを次に示します。彼の台本は私に$who_lineは役に立たず、常に空でした。私のスクリプトはプロセスを見つけるのにそれほど時間を無駄にしません。代わりに、すべてを試行し、最後に見つかった有用な値を選択します。私はxubuntu 14.04を実行していますが、この種のスクリプトを混乱させる可能性のあるlxcコンテナを実行しています。

env="$(
  ps -C init -o uid,pid | while read u p; do
    [ "$u" = "`id -u`" ] || continue
    grep -az '^DBUS_SESSION_BUS_ADDRESS=' /proc/$p/environ | xargs -0
  done | tail -1
)"

export "$env"

notify-send "test"

Xorgプロセスの環境にはが存在しないため、Trustyではこれは機能しませんDBUS_SESSION_BUS_ADDRESS。シェルからは入手できますが、Xorgプロセスからは入手できません。
ブルージェイ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.