rootとして実行する必要がある単純な定期的なcronジョブがあります。 cron操作が完了したら、Zenity(または同様のもの)を使用してユーザー1000(またはログインしたユーザーまたはすべてのユーザー)にGUI情報ダイアログボックスを表示したいと思います。
私はシンプルで簡単で迅速な解決策を探しています。この簡単なソリューションの要件を調整します。
これが私が今までいるところです。私のbashスクリプトを手動で実行すると正常に動作しますが、Anacronが実行すると何も起こりません。Gtk-WARNING **: cannot open display
ログに表示されます。 cronが実行された後、ユーザーに私のダイアログを表示したいと思います。
(関連する質問を読んだ後)cronをGUIから切り離す必要があることに気づきました。ユーザー 1000 がログインしていない場合は、次のいずれかのオプションを選択できます。
- 何もしない(単純に保ちたいので許される)
- ユーザーが次回ログインしたときに完了メッセージを含むダイアログボックスを表示する(最適)
- 他の種類の通知を表示する(注:コンピュータはメールサーバーがインストールされていないデスクトップシステムです。)
次の関連質問が見つかりました。 - Think Tank 101 - CC著作権に基づくQ&A共有プラットフォーム Anacronの操作で「Gtk-WARNING**:ディスプレイを開けません」と文句を言います。
shell - zenityの進行のためにプロセスの外部にデータを渡す方法は? - UnixおよびLinuxスタック zenityの進捗状況を得るためにプロセスの外部にデータを渡す方法は?
サンプルコード(他の質問では、基本的に私のコードと同じ):
#!/bin/bash
# Backs up the local filesystem on the external HDD
sleep 60
DISPLAY=:0.0
zenity --question --text "Do you want to backup? Be sure to turn on the HDD."
if [ $? -ne 0 ]
then exit 1
fi
*Do backup stuff here*
間違い:
(zenity:9917): Gtk-WARNING **: cannot open display:
run-parts: /etc/cron.daily/backup-on-external exited with return code 1
(私はKubuntuを使用しており、KDEソリューションはZenityよりはるかに優れていますが、すでにZenityがインストールされているため、引き続き使用できます。)
答え1
次のことをあなたのもの~/.xinitrc
(または~/.xsession
ログインマネージャを使用している場合)に追加してみてください。
while true; do
if [[ -a ~/.messages ]]; then
zenity --info --text="$(printf "%q" $(cat ~/.messages))"
rm ~/.messages
fi
sleep 10
done &
zenityがないのでこれをテストしておらず、期待.xsession
どおりに機能すると仮定します。ログインマネージャを使用したことがありません。
while
/ブロックは、done
チェックの間に10秒の遅延(sleep 10
部分的に)を置いて無期限に実行されます。各スキャンでユーザーのホームディレクトリからif
空でないファイルが呼び出されると、保護は成功します。.messages
成功すると、ファイルの内容はzenityとして読み取られ、削除されます。
吐くのはあまり嬉しくないけどprintf
大丈夫だと思います。
入力した内容は~/.messages
cronからリダイレクトし、ファイルの所有者とグループを適切に変更したことを確認する必要があります。たぶん、次のようなものがあります。
10 * * * * /usr/bin/mything && echo "mything completed" > /home/username/.messages && chown username:groupname /home/username/.messages
答え2
私のシステムはUbuntu 13.04です。 anacrontab経由であなたに似たスクリプトを実行しましたが、うまくいきました。この試み..
クローンタブを設定してください。
$ cat /path/crontabfile
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
* * * * * /bin/bash /path/anacron-tst/s1.sh
代替案:アナクロンタブを設定してください。
$ cat /etc/anacrontab
### original
.. ,, ..
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
HOME=/root
LOGNAME=root
# These replace cron's entries
1 5 cron.daily run-parts --report /etc/cron.daily
7 10 cron.weekly run-parts --report /etc/cron.weekly
@monthly 15 cron.monthly run-parts --report /etc/cron.monthly
### end-original
### my custom lines ..
SHELL=/bin/bash
HOME=/home/me
LOGNAME=me
1 2 me1 /bin/bash /path/anacron-tst/s1.sh
スクリプト内...
$ cat /path/anacron-tst/s1.sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
export DISPLAY=:0.0
export XAUTHORITY=/home/me/.Xauthority
zenity --question --text "Backup time .. is HDD connected?"
if [ $? -ne 0 ]; then
echo "No confirmation .. quiting"
exit 1
else
echo "Will attempt backup now .."
fi
これは man 5 anacrontab からのものです。
.. lines can be of three kinds: job-description lines, environment assignments, or empty lines.
Environment assignment lines are of the form: VAR = VALUE
.. ,, ..
The assignment takes effect from the next line to the end of the file, or
to the next assignment of the same variable.
これは、ルートにインストールされているcrontabで使用されます。次の行を含むようにスクリプトを編集しました。"XAUTHORITY=/home/me/.Xauthorityのエクスポート"。この方法で作業する必要があります。
答え3
これまでに私が見つけたすべてのコンテンツのレポートは次のとおりです。
このソリューションはAsk Ubuntuで提供されています。
これは現在私にとって効果的であり、これまで何の問題も発見されていません。
ACTIVE=$(ck-list-sessions | awk -F' = ' '
function f(){if(A=="TRUE"){P=U"\t"D;gsub("'"'"'","",P);print P}}
$1=="\tunix-user"{U=$2}
$1=="\tx11-display"{D=$2}
$1=="\tactive"{A=$2}
END{f()} /^[^\t]/{f()}
')
USERID=${ACTIVE% *} # tab
USERNAME=$(getent passwd $USERID|cut -f1 -d':')
DISPLAY=${ACTIVE#* } # tab
DISPLAY="$DISPLAY" su $USERNAME -c "zenity --info --title='My Title' --text='My text. Notice the single quotes.'"
しかし、私はinform-sendコマンドをテストしてきました(言及済み)。ここ)そして私の場合は、よりよく合うようです...
残念ながら、KDEの欠点は、通知がすぐに非表示になり、タイムアウトを無効にする方法が見つからないことです(-t 0は機能しません)。現在のユースケースでは、ボタンをクリックして閉じる必要があるダイアログボックスを好む傾向があります。とにかく通知送信の詳細は次のとおりです。
通知転送コマンド
通知の送信コマンドを使用すると、通知デーモンを介してコマンドラインからユーザーにデスクトップ通知を送信できます。これは、デスクトップユーザーにイベントを知らせたり、ユーザーを邪魔することなく、何らかの形の情報を表示するのに役立ちます。次のパッケージをインストールする必要があります。
$ sudo apt-get install libnotify-bin
この例では、コマンドラインから簡単なデスクトップ通知を送信するには、次のように入力します。
notify-send "rsnapshot done :)"
しかし、解決策を探して、私が本当に好きないくつかの事実も発見しました!すべてのスクリプトからZenityへのすべての呼び出しを削除し、easybashguiに置き換えます。
EasybashGUI
http://sites.google.com/site/easybashgui/
EasyBashGUIは、KDEまたはIs GNOME running、Yadに従って、yad、gtkdialog、kdialog、zenity、Xdialog、(c)dialog、hiptail、またはbash組み込み機能を使用して簡単なGUI機能を提供するように設計された* BSDおよびGNU / Linux用のBashライブラリです。 /Gtkdialog/Xdialogがインストールされ、最後にXサーバーが起動します。
今後、Zenityを置き換えるYadも見つけました。 easybashguiはZenity、yad、gtkdialog、kdialog、Xdialog、(c)dialog、hiptail、またはbashの組み込み機能を使用/呼び出しできます。したがって、私はZenityを段階的に廃止し、適切な場合はyadを使用します。
庭
シェルスクリプトまたはコマンドラインでグラフィックダイアログを表示する - Google Project Hosting http://code.google.com/p/yad/
Yad(Another Dialog)は、カスタムボタン、追加ダイアログ、通知アイコンのポップアップメニューなど、多くの機能強化を含むZenityのフォークです。
このフォークを作った理由は大きく2つあります。 1つ目は、libgladeやgnome-canvasなど、廃止されたライブラリへの依存関係を削除することです。第二 - Zenityは私に放棄されたプロジェクトのように見えます。長い間、ChangeLogには「次にアップグレードされたバージョン...」と「翻訳アップデート」のみが含まれていましたが、開発者/メンテナンス者が無視した多くの興味深いアイデアがGNOME Bugzillaにあります。
ブック
don_crisstiが述べたように、unix.stackexchange.comのソリューションが関連する可能性があります。
答え4
Mel Boyceの答えに基づいて、これは私にとって効果的でした。これはKDEに基づいています。しかし、Zenityでもテストしましたが、同じ方法が機能しました。これは基本的にMel Boyceが推奨するものと同じですが、私に合うようにいくつかの調整が必要です。たとえば、updateNotification.txt ファイルは削除しません。そして私はprintfを使用しません。
アップデートプログラムスクリプトには以下が含まれます。
DATE_STAMP=` date`
echo "\t***The software has been updated to version ${LATEST} on ${DATE_STAMP}***"
echo "The software has been updated to version ${LATEST} on ${DATE_STAMP}. Please close and reopen the program if it is current running. If you have any issues or questions, please write us at [email protected]. Thank you." > /home/$USERN/.updateNotification.txt
次に、/home/$USERN/.kde/Autostart/updateNotificationChecker.shでスクリプトを実行します。
#!/bin/bash
while true; do
if [[ -s ~/.updateNotification.txt ]]; then
read MSGFE < ~/.updateNotification.txt
kdialog --title 'The software has been updated' --msgbox "$MSGFE"
cat /dev/null > ~/.updateNotification.txt
fi
sleep 300
done
exit 0