Задание 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
- Лучшая версия скрипта: Как я могу показать сообщения уведомления-отправки, инициированные crontab?
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. Здесь представлено, как работает скрипт: