Вопрос или проблема
Я в настоящее время пишу небольшую службу systemd, которая может понадобиться для выключения компьютера. Я хотел бы разослать сообщение всем пользователям, например, Этот компьютер будет выключен в XXX, не забудьте сохранить свою работу.
Для пользователей терминала я мог бы использовать wall
, но для пользователей, у которых нет открытого терминала, это не вариант. Я знаю, что все пользователи на этом компьютере используют X/Gnome, так что у них установлен клиент уведомлений freedesktop. Однако мне не ясно, как я могу использовать системную шину (?) для отправки уведомлений freedesktop.
Как я могу это сделать?
Вы не используете системную шину, а сессии отдельных пользователей!
вы получаете все текущие активные пользовательские сессии
loginctl list-sessions
(Я часто использую необязательный JSON-вывод инструментов systemd. Например, здесь loginctl list-session --output json | jq -r '.[].user'
просто даст мне список пользователей. `… | jq -r ‘.[] | select (.state == “active”) | .user’ даст мне тех, кто активно сидит перед своими экранами.)
Затем вы просто запускаете эмиттер уведомлений на пользовательской шине целевого пользователя. Это просто:
systemd-run --user --machine=${userFromAbove}@.host notify-send --urgency=low 'Кофе готов!'
Записываем это в один (zsh) скрипт:
#!/usr/bin/zsh
# (должно работать и в bash)
# запускайте себя от имени root, если вы еще не root.
[[ $(id -u) == "0" ]] || {sudo $0 ; exit $?}
for user in $(loginctl list-session --output json \
| jq -r '.[] | select (.state == "active") | .user') ; do
systemd-run \
--user \
--machine=${user}@.host \
notify-send \
--urgency=normal \
'Свежие крампеты на кухне! Парень по имени Crud Puppy принёс их.'
done
Ответ или решение
Эффективная трансляция сообщений пользователям в настольных средах
Ваша задача заключается в разработке systemd-сервиса, который будет уведомлять всех пользователей о предстоящем завершении работы компьютера. Такое уведомление должно быть доступно как для пользователей, работающих в терминале, так и для тех, кто использует графический интерфейс без открытого терминала.
Использование wall
для терминальных пользователей
Для пользователей, работающих в текстовом терминале, можно использовать команду wall
, которая отправляет сообщения всем активным сеансам терминала. Но это не подходит для пользователей, которые используют графическую оболочку, такую как GNOME.
Приоритет фреймворка Freedesktop Notifications
Поскольку все пользователи на вашем компьютере работают в окружении X/GNOME, у них установлен клиент для уведомлений Freedesktop, который может получать уведомления. Основная задача — отправить уведомление каждому активному пользователю. Однако, уведомления должны быть отправлены через сессию каждого пользователя.
Ответ на запрос: как это сделать
Для отправки уведомления через систему Freedesktop необходимо использовать системный вызов, который учитывает индивидуальную сессию пользователя. Вы можете начать с получения списка активных сессий пользователей с помощью следующей команды:
loginctl list-sessions
Кроме того, для упрощения работы и фильтрации активных пользователей, вы можете использовать команду с выходом в формате JSON:
loginctl list-sessions --output json | jq -r '.[] | select (.state == "active") | .user'
Этот подход позволяет получить только тех пользователей, которые в данный момент находятся в активности на рабочем столе.
После этого можно воспользоваться консольной командой systemd-run
, чтобы отправить уведомления:
systemd-run --user --machine=${userFromAbove}@.host notify-send --urgency=low 'Ваше сообщение!'
Пример скрипта для широковещательной рассылки сообщений
Вот пример Zsh (или Bash) скрипта, который осуществляет массовую рассылку уведомлений всем активным пользователям:
#!/usr/bin/zsh
# Скрипт следует исполнять от имени администратора
# Проверка на выполнение скрипта с правами root
[[ $(id -u) == "0" ]] || {sudo $0 ; exit $?}
# Цикл для отправки уведомлений
for user in $(loginctl list-sessions --output json \
| jq -r '.[] | select (.state == "active") | .user') ; do
systemd-run \
--user \
--machine=${user}@.host \
notify-send \
--urgency=normal \
'Это сообщение предназначено для вас: Компьютер будет выключен в XXX. Не забудьте сохранить свою работу.'
done
Заключение
Следуя приведенным инструкциям, вы сможете создавать уведомления для пользователей в настольных средах, использующих X/GNOME. Это решение удобно и эффективно, так как учитывает индивидуальные сеансы пользователей и позволяет избежать проблем с отсутствием открытых терминалов.
Используя такой подход, вы обеспечите всем пользователям необходимую информацию о планируемых действиях с компьютером, что поможет избежать потери данных и оптимизирует процесс работы в многопользовательских средах.