Використання сповіщення-відправлення за допомогою cron


32

Я використовую Arch Linux з KDE / Awesome WM. Я намагаюся взяти notify-sendна роботу cron.

Я спробував налаштування DISPLAY/ XAUTHORITYзмінні та працює notify-sendз "sudo -u", і все без результату.

Я можу зателефонувати сповіщенням-надіслати інтерактивно з сеансу та отримувати сповіщення.

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 потрібно встановити. І після жорсткого кодування цього значення за допомогою значення, яке я отримав під час свого інтерактивного сеансу, крихітне маленьке повідомлення "привіт" почало спливати на екран щохвилини!

Але уловлювач полягає в тому, що ця змінна не є постійною для цієї посади, тому я спробую запропонований там проект, який пропонується.

[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здається, не підтримується сповіщення-відправлення (принаймні, безпосередньо), чи є якась інша система сповіщень, яка є більш cronдружньою, яку я можу використовувати?


Це повинно працювати, наскільки я бачу. Чому б ви не додали &>>/tmp/crontestдо рядка надсилання сповіщень і не подивитесь, чи notify-sendдає повідомлення про помилки
Graeme

З цікавості ви спробували моє рішення? Це здається набагато простішим і чудово працював на моєму Debian. Я прошу просто знати, чи це Debian специфічно чи ні
terdon

@terdon Я спробував ваше рішення (просто швидкий тест) і, здається, працює на моїй системі Debian. Мені хотілося б дізнатися, чи вона взагалі застосовна, оскільки вона справді простіша.
Марко

@Marco Я перебуваю на LMDE (фактично тестування Debian) і використовую Cinnamon як DE. Не можу вам сказати, чи працює вона поза цим.
terdon

@Marco & terdon: хлопці Ubuntu можуть зробити так: ubuntuforums.org/showthread.php?t=1727148
justsomeone

Відповіді:


29

Вам потрібно встановити DBUS_SESSION_BUS_ADDRESSзмінну. За замовчуванням cron не має доступу до змінної. Щоб виправити це, поставте кудись наступний скрипт і зателефонуйте йому, коли користувач увійде в систему, наприклад, використовуючи awesome та run_onceфункцію, згадану у вікі. Буде робити будь-який метод, оскільки це не шкодить, якщо функція викликається частіше, ніж потрібно.

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


Чи не було б це ризиком для безпеки? security.stackexchange.com/questions/71019/…
rubo77

@Gilles Як ти міг це зробити в одному рядку, як ти згадував у чаті?
rubo77

Я спробував так багато інших відповідей, не включаючи DBUS на ubuntu 15.10, і нічого не вийшло. Цей простий і працює бездоганно.
бастіан

16

Вам потрібно встановити змінні у самій crontab:

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

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

Не sudoпотрібно, принаймні, не в моїй системі.


Дякую тердон за ваш час. Це здається простим рішенням. На жаль, це не спрацювало для мене,
justsomeone

@justsomeone так, може, це може залежати від середовища на робочому столі.
terdon

Я думаю, це має щось спільне з distro або Desktop Environment. Для користувачів Ubuntu рішення прямого напрямку, здається, добре спрацьовують з того, що я бачив на інтернет-форумах.
justsomeone

@justsomeone Я на Debian (LMDE), використовуючи Cinnamon як DE. Може мати щось спільне з тим, як запускається X, або із системою сповіщень, яку використовує DE, dunno.
terdon

Підтверджено, що він працює на Ubuntu 14.04 / 14.10. З GNOME та Unity.
Джордон Бедвелл

8

Найбезпечніший спосіб отримати екологічні змінні, пов’язані з сеансом X, - це отримати їх з оточення процесу користувача, який увійшов до X. Ось адаптація сценарію, який я використовую з цією ж метою (хоча DBUS_SESSION_BUS_ADDRESS не робить ' t, здається, для мене проблема на 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 викликають whoдрук дисплея замість 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"

Це не працює для мене на Trusty, оскільки в who_lineкоманді немає друкованих tty . Вихід виглядає так me :0 2015-09-23 10:40 ? 17234.
blujay

1
@blujay, оновлено.
Graeme

Дякую, це працює. Однак, як я розмістив в окремій відповіді, є ще простіше рішення.
blujay

@blujay Так, це була спроба портативної відповіді. Не впевнений, що це дійсно можливо, але це все ж має працювати в більшості випадків.
Graeme

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корисну. Я ще не знайомий з Кроні, але створив свій "crontab" як, /etc/cron.d/mycronjobsі я не впевнений, чи потрібне це ім'я файлу, чи він просто читає все в каталозі cron.d.

Я знайшов рішення тут https://wiki.archlinux.org/index.php/Desktop_notifications


2

Я використовую i3 на Ubuntu 18.04. Мій спосіб вирішити це:

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


1

Цього достатньо для того, щоб зробити роботу надсилати сповіщення для мене в рамках роботи на Ubuntu Trusty:

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

Він просто експортує DISPLAYдля користувача cronjob як. Це працює для мене без налаштування XAUTHORITYабо DBUS_SESSION_BUS_ADDRESS.


1
Працює і на Ubuntu 16.04. У мене фактично є запуск Cron скрипта Perl, яка система () sa bash script, яка запускає інший скрипт Perl, який виконує систему ("сповістити-надіслати ..."). Додавання команди експорту до скрипту bash змінило середовище для цього сценарію, який останній скрипт Perl потім успадкував і став доступним для системи ("notify-send ..."). Добре знайдіть блюджай!
Тім

1

Для тих, хто працює в Linux, які зручно встановлюють пакети Python, я щойно випустив програму 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, що грає щебетати щогодини

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

0

Використання судо:

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

Добре знати :

Крон, що працює під коренем, не має доступу до x, тому всі команди gui не відображатимуться, одне просте рішення - додати root до авторизованого користувача 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"

Це не працює для мене на Trusty, оскільки середовище процесу Xorg не має DBUS_SESSION_BUS_ADDRESS. Я можу отримати його з моїх оболонок, але не від процесу Xorg.
blujay
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.