Как вывести результат скрипта в терминал через cron: настройка DISPLAY и типичные ошибки

Представьте: вы настроили идеальный скрипт для мониторинга диска, который должен показывать результаты в отдельном окне терминала. Вручную всё работает как часы, но при запуске через cron – тишина. Проблема кроется в тонкостях взаимодействия cron с графической средой, и сейчас мы разберёмся, как заставить их работать в паре.

Почему cron «не видит» ваш дисплей

Когда вы запускаете команду вручную, система автоматически подставляет переменные окружения – включая DISPLAY=:0, которая указывает на основной X-сервер (тот самый, куда выводится ваш рабочий стол). Но cron работает в изолированном окружении без доступа к этим настройкам.

Вот что происходит под капотом:

  • Cron – демон, работающий вне пользовательской сессии (даже если задача добавлена через crontab -e)
  • Графические приложения в Linux требуют:
    – Адрес X-сервера (DISPLAY)
    – Права доступа (обычно хранятся в ~/.Xauthority)
  • Без этих параметров xterm просто не знает, куда выводить окно

Проверьте сами: выполните env | grep DISPLAY в терминале и сравните с выводом cron-задачи, где первая команда – env > /tmp/cron_env.log.

DISPLAY=:0 – магия или логика?

Вот типичная ошибка в настройке:

# Не работает в cron:
xterm -e 'your_script.sh'

# Рабочий вариант:
DISPLAY=:0 xterm -e 'your_script.sh'

Что на самом деле делает DISPLAY=:0:

  1. Указывает на первый запущенный X-сервер (обычно основной дисплей)
  2. Имеет формат hostname:display_number.screen_number
  3. Локальный сервер сокращается до :0 (эквивалент :0.0)

Но есть нюанс — в некоторых сценариях:

  • DISPLAY может быть :1, если вы вошли через второй сеанс
  • На серверах без графической оболочки переменная вообще отсутствует
  • Wayland использует другой синтаксис (WAYLAND_DISPLAY=wayland-0)
СитуацияЗначение DISPLAY
Стандартный десктоп:0
Второй X-сервер:1
Запуск из SSH-сессииНе задано

Надёжные способы указать DISPLAY для cron

Способ 1 – жёсткое задание в crontab (подходит для простых случаев):

# В начале файла crontab:
DISPLAY=:0
XAUTHORITY=/home/user/.Xauthority

# Затем ваши задачи:
* * * * * xterm -e 'echo "Работает!"'

Способ 2 – динамическое определение DISPLAY (рекомендуется):

1. Создайте скрипт для сохранения текущих настроек:

#!/bin/bash
echo "export DISPLAY=$(loginctl list-sessions | grep $(id -u) | awk '{print $3}')" > ~/.current_display
echo "export XAUTHORITY=$HOME/.Xauthority" >> ~/.current_display

2. Добавьте его в автозагрузку (через ~/.config/autostart/ или systemd)

3. В cron-задаче:

* * * * * source ~/.current_display && xterm -e 'your_script'

    Кстати, если используете Wayland (как в Ubuntu 22.04+), вместо DISPLAY потребуется задать WAYLAND_DISPLAY. Проверить текущий протокол можно командой echo $XDG_SESSION_TYPE.

    Способ 3 – через systemd (современная альтернатива cron):

    # Создайте сервисный файл
    systemctl --user edit --force --full my-xterm.service
    
    [Service]
    Environment="DISPLAY=:0"
    ExecStart=/usr/bin/xterm -e '/path/to/script.sh'
    
    # Таймер для запуска каждые 5 минут
    systemctl --user edit --force --full my-xterm.timer
    
    [Timer]
    OnCalendar=*:0/5

    Частые ошибки

    • Путь к .Xauthority без учёта домашней директории (используйте $HOME)
    • Попытка использовать ~ в cron (раскрывается только в интерактивных сессиях)
    • Забыли добавить -hold в xterm, и окно сразу закрывается

    Если после всех настроек окно всё равно не появляется, проверьте:

    1. Права на .Xauthority (должны совпадать с пользователем cron-задачи)
    2. Запущен ли X-сервер (команда ps aux | grep Xorg)
    3. Не блокирует ли брандмаузер соединение с локальным дисплеем

    Как временное решение можно разрешить всем пользователям доступ к X-серверу (но это небезопасно!):

    xhost +local:

    Помните: DISPLAY=:0 – не всегда панацея. В системах с несколькими активными сессиями или при перезапуске X-сервера значение может измениться. Для критически важных задач лучше использовать методы с динамическим определением дисплея или переход на systemd-сервисы, которые интегрированы с пользовательской сессией.

    Добавить комментарий

    Все поля обязательны к заполнению. Ваш адрес email не будет виден никому.

    Новое
    Интересное