Вы можете сохранить свой список 150 5 символьных строк в файле сначала и затем выполнили цикл для захвата шаблонов -
for i in `cat file`
do
cat mvsfile | grep -i $i >> matched_lines
done
Необходимо установить DBUS_SESSION_BUS_ADDRESS
переменная. Кроном по умолчанию не имеет доступа к переменной. Для исправления это поместило следующий сценарий где-нибудь и называет его, когда пользователь входит в систему, например, с помощью потрясающего и run_once
функция упоминается на Wiki. Любой метод сделает, так как он не вредит, если функция вызывается чаще, чем необходимый.
#!/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 evironment. Затем в сценарии, названном кроном, Вы импортируете переменную путем определения источника сценария:
if [ -r "$HOME/.dbus/Xdbus" ]; then
. "$HOME/.dbus/Xdbus"
fi
Необходимо установить переменные в самом crontab:
DISPLAY=:0.0
XAUTHORITY=/home/matrix/.Xauthority
# m h dom mon dow command
* * * * * /usr/bin/notify-send "hello"
Нет sudo
необходимый, по крайней мере, не в моей системе.
Самый безопасный способ получить X связанных с сессией переменных окружения состоит в том, чтобы получить их от среды процесса пользователя, который зарегистрирован на X. Вот адаптация сценария, который я использую для точно той же цели (хотя DBUS_SESSION_BUS_ADDRESS, кажется, не проблема для меня на 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"
who_line
команда. Вывод похож me :0 2015-09-23 10:40 ? 17234
.
– blujay
04.10.2015, 02:15
Это менее сложный сценарий, чем тот, который предоставил Грэм. Его скрипт у меня не работал, $ 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"
Я использую этот скрипт в cron для записи MPD, который теперь проигрывается в 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 использует свой собственный notification-deamon IIRC.
Этого достаточно, чтобы заставить notify-send работать для меня в cronjob на Ubuntu Trusty:
#!/bin/bash
export DISPLAY=$(who -u | awk '/\s:[0-9]\s/ {print $2}')
Это просто экспортирует DISPLAY
для пользователя, от имени которого запущен cronjob. Это работает для меня без установки XAUTHORITY
или DBUS_SESSION_BUS_ADDRESS
.
Для тех, кто работает в Linux и кому удобно устанавливать пакеты Python, я только что выпустил программу notify-send-headless, которая хорошо работает у меня. Она ищет в /proc
необходимое имя пользователя и переменные окружения, а затем запускает notify-send
с этими переменными (при необходимости она будет использовать sudo
для переключения на нужного пользователя).
Этот однострочник работал для меня в Manjaro с Cronie:
# 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
полезным. FWIW, Cronie использует crond и должен быть обратно совместим с Vixie cron.
Я нашел решение здесь https://wiki.archlinux.org/index.php/Desktop_notifications
Обновление: все еще работает в 2021 году. Я добавил эти советы в свой файл /etc/crontab.
# After installing cronie:
# systemctl start cronie
# systemctl enable cronie
# After editing this file:
# chmod 600 /etc/crontab
# crontab /etc/crontab
# Check that the changes are set:
# crontab -l
Вы также можете создать скрипт:
#!/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"
По крайней мере, это для меня. Кажется, что все зависит от конфигурации среды.
Что бы это ни стоило....
Мне пришлось использовать ВСЕ следующие средства в Debian Jessie, чтобы это заработало...
export DISPLAY=:0.0
export HOME=/home/$user
source "$HOME/.dbus/session-bus/*-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, работающий под root, не имеет доступа к x, поэтому все команды графического интерфейса не будут отображаться, одно простое решение — добавить root к авторизованному пользователю x для текущего пользователя x с помощью этой команды
из пользовательской оболочки x
xhost local:root
или
sudo -u $currentxuser xhost local:root
Я использую i3 в Ubuntu 18.04. Мой способ решить эту проблему:
* * * * * XDG_RUNTIME_DIR=/run/user/$(id -u) notify-send Hey "this is dog!"
Используйте printenv
для печати переменных среды с вашего обычного терминала. А затем вставьте все переменные среды в начало файла crontab.