Задание Cron для запуска скрипта Python при перезагрузке не работает

Я новичок в Linux, и я прочитал и следовал многим инструкциям для запуска сценария Python при перезагрузке, но ни один из них не работал:

это команда, которую я хочу выполнить:

/usr/bin/python3 /home/am/projects/AMAcc/map.py

я использовал crontab -e и добавил

@reboot /usr/bin/python3 /home/am/projects/AMAcc/map.py

Я старался sudo crontab -e и добавил ту же команду

Я даже отредактировал /etc/crontab файл и добавленная выше команда.

Пробовал добавлять #!/usr/bin/python3 в верхней части моего кода Python и изменения его разрешений, таких как:sudo chmod a+x map.py

Как свидетельствуют документы, все пользователи смогут запускать задания cron, если cron.deny Файл существует, но он пуст, поэтому я попытался создать пустой cron.deny файлы в обоих /etc/cron.deny а также /usr/lib/cron/cron.deny, Но все равно не повезло, что я работал в cron.

Что я делаю?

1 ответ

Решение

Для запуска любого приложения с графическим интерфейсом из Cron вы должны экспортировать несколько переменных окружения рабочего стола. В большинстве случаев вполне достаточно экспортировать текущий $DISPLAY значение. Я бы предложил вам создать дополнительный скрипт запуска (bash), который запустит ваше приложение.

В этом ответе предоставляется надежный подход, как найти и экспортировать текущего пользователя $DISPLAY значение. Но есть проблема. Пока пользователь не вошел в DE, $DISPLAY значение не установлено. Так что мы могли бы добавить дополнительное условие, как это сделано в следующих ответах:

# Get the value of the $DISPLAY variable for the current user. Unset it just in case this is a `ssh -X` connection
unset DISPLAY;
while [ "$DISPLAY" == "" ]; do
        export DISPLAY=$(w "$USER" | awk 'NF > 7 && $2 ~ /tty[0-9]+/ {print $3; exit}' 2>/dev/null) && sleep 3
done
  • Это условие работает во всех других случаях, но оно не выполняется в течение @reboot Cron рабочие места, и я не могу понять причину. Таким образом, в приведенном ниже сценарии используется другой подход, чтобы проверить, вошел ли пользователь в Mate.

Некоторым приложениям нужно несколько переменных (например, см. Этот и этот ответы) как $DBUS_SESSION_BUS_ADDRESS а также $DESKTOP_SESSION, На мой взгляд, лучший подход - найти процесс сеанса рабочего стола текущего пользователя в каталоге /proc (обрабатывать информацию псевдофайловой системой) и экспортировать все переменные из файла environ это внутри /proc/process-number,

Я создал небольшой проект под названием cron-gui-launcher, посвященный этому. Это работает, но это не проверено для всех случаев пользователя (как текущий). Здесь я извлек основную часть, которая относится к Mate DE, и сделал модификацию, упомянутую выше.

1. Создайте исполняемый файл с таким содержимым:

#!/bin/bash -e

# Check whether the user is logged in Mate
while [ -z "$(pgrep mate-session -n -U $UID)" ]; do
        sleep 3 && count=$((count+1)) && echo "$count" > /tmp/mate-cron.log
done

# Get the content of the Current-Desktop-Session Environment File as an array:
EnvVarList=`cat -e "/proc/$(pgrep mate-session -n -U $UID)/environ" | sed 's/\^@/\n/g'`

# Export the Current-Desktop-Session Environment Variables:
for EnvVar in $EnvVarList; do
        echo "$EnvVar" >> /tmp/mate-cron.log
        export "$EnvVar"
done

# Execute the list of the input commands
nohup "${1}" >/dev/null 2>&1 &

exit 0

2. Сейчас в crontab использовать:

@reboot /path-to-the/script "your-application"

3. Примечания:

  • Этот скрипт не должен работать с рутом crontab, Из-за переменных $UID а также $USER, Вы можете заменить их UID и ИМЯ определенного пользователя.

  • Для другого изменения DE mate-session из этой части $(pgrep mate-session -n -U $UID) с именем процесса другого DE, например gnome-session,

  • Может быть, для приложений с графическим интерфейсом, которые выполняются при запуске системы, лучше создать запись в Startup Applications. Для Mate DE: Control Centre > Personal > Startup Applications ( источник).

4. Здесь представлено, как работает скрипт:

Другие вопросы по тегам