Почему этот cronjob не работает?

В настоящее время пытаюсь настроить cron job с python Скрипт, который я клонировал отсюда. Иерархия для достижения моего сценария может быть описана как ниже:

                                    /home
                                      |
                                      |
                            /Daily-Reddit-Wallpaper
                                      |
                                      |
                         change_wallpaper_reddit.py

Теперь это работает, когда я использую команду, python change_wallpaper_reddit.py --time new внутри Daily_Reddit_Wallpapers папка. Тем не менее, когда я пытаюсь команду, * * * * * python ./change_wallpaper_reddit.py --time newЯ получаю ошибку:

change_wallpaper_reddit.py: command not found

Когда я пытаюсь вызвать * * * * * python ~/Daily-Reddit-Wallpaper/change_wallpaper_reddit.py, Я получил:

usage: anaconda [-h] [--show-traceback] [--hide-traceback] [-v] [-q] [--color]
                [--no-color] [-V] [-t TOKEN] [-s SITE]
                ...
anaconda: error: argument : invalid choice: 'Daily-Reddit-Wallpaper' (choose from 'auth', u'label', u'channel', 'config', u'copy', u'download', 'groups', u'login', 'logout', u'notebook', 'package', 'remove', 'search', 'show', u'upload', u'whoami')

Я не понимаю, почему это происходит.

2 ответа

Решение

Проблема в том, что скрипт не предназначен для работы с Cron. Он использует несколько переменных среды, которые недоступны из Cron, и они различаются в зависимости от среды рабочего стола текущего пользователя. По этой причине на его странице описывается еще один способ запуска при запуске. Но можно установить значения этих переменных во время работы CronJob.

Например, когда это среда рабочего стола Ubuntu по умолчанию, ключевые слова для поиска должны выглядеть так: "gsettings" и "cron", тогда наш поиск приведет нас к проводным темам, таким как: Фон не меняется с помощью gsettings из cron, где мы могли бы найти дополнительные объяснения как:

Если вы запускаете сценарий из собственной среды (например, из окна терминала или из автозагрузки), будет задан ряд переменных среды. cron однако ваш скрипт запускается с ограниченным набором переменных среды.

Редактировать gsettings успешно из cronнужно установить DBUS_SESSION_BUS_ADDRESS переменная окружения. Вы можете сделать это, добавив две строки в ваш скрипт, как описано здесь...


Запустите: Daily-Reddit-Wallpaper через Cron через скрипт запуска

Здесь мы создадим скрипт запуска, который установит необходимые переменные среды в зависимости от выбранной (по аргументу) среды рабочего стола.

1. Сначала клонируем Daily-Reddit-Wallpaper, а также устанавливаем зависимости:

cd ~
git clone https://github.com/ssimunic/Daily-Reddit-Wallpaper.git
cd ~/Daily-Reddit-Wallpaper
sudo apt-get install python-pip
pip install -r requirements.txt

2. Создайте файл скрипта - change_wallpaper_reddit.sh:

cd ~/Daily-Reddit-Wallpaper
touch change_wallpaper_reddit.sh
chmod +x change_wallpaper_reddit.sh
nano change_wallpaper_reddit.sh

Содержание сценария:

#!/bin/sh

# Reference: https://Ask-ubuntu.ru/a/911958/566421

# Set the script home directory:
SHOME=Daily-Reddit-Wallpaper

# Set the output folder in the home directory to save the Wallpapers to:
DIR=Pictures/Wallpapers

# Set the --time parameter value
TIME=now

# Check if the Desktop Environment is changed:
LAST=$(cat "$HOME/$SHOME/last-desktop-environment.log")
if [ "$1" != "$LAST" ]
then
    # Get the name of the last saved wallpaper image:
    IMG=$(ls -Art $HOME/$DIR | tail -n 1)
    rm $HOME/$DIR/$IMG
fi

# Desktop Environment cases:
if [ -z ${1+x} ] || [ "$1" = "gnome" ] || [ "$1" = "unity" ]
then
    # Set the necessary environment variables - PID=$(pgrep gnome-session -u $USER) - UBUNTU/UNITY/GNOME:
    export GNOME_DESKTOP_SESSION_ID=true
    export DBUS_SESSION_BUS_ADDRESS=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep gnome-session -n)/environ | cut -d= -f2-)

    # Run the script:
    $HOME/$SHOME/change_wallpaper_reddit.py --time $TIME --output $DIR

elif [ "$1" = "kde" ]
then
    # Set the necessary environment variables - KUBUNTU/PLASMA/KDE:
    export KDE_FULL_SESSION=true
    export DBUS_SESSION_BUS_ADDRESS=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep startkde -n)/environ | cut -d= -f2-)

    # Run the script:
    $HOME/$SHOME/change_wallpaper_reddit.py --time $TIME --output $DIR

elif [ "$1" = "mate" ]
then
    # Set the necessary environment variables - Ubuntu MATE/MATE:
    export DESKTOP_SESSION=mate
    export DBUS_SESSION_BUS_ADDRESS=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep mate-session -n)/environ | cut -d= -f2-)

    # Run the script:
    $HOME/$SHOME/change_wallpaper_reddit.py --time $TIME --output $DIR

elif [ "$1" = "lxde" ]
then
    # Set the necessary environment variables - type 'echo $DISPLAY` to find your current display - LUBUNTU/LXDE:
    export DESKTOP_SESSION=Lubuntu
    export DBUS_SESSION_BUS_ADDRESS=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep lxsession -n)/environ | cut -d= -f2-)
    export DISPLAY=$(w $(id -un) | awk 'NF > 7 && $2 ~ /tty[0-9]+/ {print $3; exit}')

    # Run the script:
    $HOME/$SHOME/change_wallpaper_reddit.py --time $TIME --output $DIR

elif [ "$1" = "xfce4" ]
then
    # Set the necessary environment variables - XUBUNTU/XFCE4:
    export DBUS_SESSION_BUS_ADDRESS=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pgrep xfce4-session -n)/environ|cut -d= -f2-)

    # Run the script:
    $HOME/$SHOME/change_wallpaper_reddit.py --time $TIME --output $DIR

    # Get the name of the last saved wallpaper image:
    IMG=$(ls -Art $HOME/$DIR | tail -n 1)

    # Since 'change_wallpaper_reddit.py' doesn't work properly with xfce4 we shall set the background manually:
    xfconf-query --channel xfce4-desktop --property /backdrop/screen0/monitor0/workspace0/last-image --set $HOME/$DIR/$IMG

    # Property list:      xfconf-query --channel xfce4-desktop --list
    # Current settings:   xfconf-query -c xfce4-desktop -p /backdrop -lv
    # Set 'zoomed' style: xfconf-query --channel xfce4-desktop --property /backdrop/screen0/monitor0/workspace0/image-style --set 5
    # References:         https://Ask-ubuntu.ru/q/380550/566421 and https://Ask-ubuntu.ru/q/414422/566421

else
    echo "Wrong argument. It must be:"
    echo "  - empty (default) = gnome = unity"
    echo "  - kde"
    echo "  - lxde"
    echo "  - mate"
    echo "  - xfce4"
fi

# Save current value of the Desktop Environment variable:
echo "$1" > "$HOME/$SHOME/last-desktop-environment.log"

Этот скрипт имеет один аргумент $1, которые определяют его поведение в зависимости от выбранной (от вас) среды рабочего стола (DE). Возможные значения:

  • gnome или же unity или же empty(по умолчанию) - при использовании Ubuntu DE по умолчанию;
  • kde- когда вы используете KUbuntu DE;
  • lxde- когда вы используете LUbuntu DE;
  • mate- когда вы используете Ubuntu MATE DE;
  • xfce4- когда вы используете XUbuntu DE.

Также вы можете настроить эти исходные параметры:

  • SHOME=установите папку, в которойDaily-Reddit-Wallpaper находится в вашей системе.
  • DIR=установить выходную папку в домашнем каталоге, чтобы сохранить обои - значение по умолчанию (Pictures/Wallpapers) используется в приведенном выше сценарии.
  • TIME=установить значение--timeпараметрchange_wallpaper_reddit.py,

3. СоздатьCronJob (crontab -e), который выполняетchange_wallpaper_reddit.sh (например, каждый час):

  • Если вы используете Ubuntu DE по умолчанию, этот CronJob может быть:

    0 * * * * /home/<your user name>/Daily-Reddit-Wallpaper/change_wallpaper_reddit.sh > /home/<your user name>/Daily-Reddit-Wallpaper/cron.log 2>&1
    

    также этот синтаксис принесет тот же результат:

    0 * * * * /home/<your user name>/Daily-Reddit-Wallpaper/change_wallpaper_reddit.sh gnome > /home/<your user name>/Daily-Reddit-Wallpaper/cron.log 2>&1
    
  • Если вы используете KUbuntu DE, например, этот CronJob может быть:

    0 * * * * /home/<your user name>/Daily-Reddit-Wallpaper/change_wallpaper_reddit.sh kde > /home/<your user name>/Daily-Reddit-Wallpaper/cron.log 2>&1
    
  • Для устранения неполадок проверьте файл журнала:cat /home/$USER/Daily-Reddit-Wallpaper/cron.log

Вуаля. Работает!


Ссылки и дальнейшее чтение:

Помните, что cronjab выполняется в оболочке с ограниченными настройками среды. Под этим я подразумеваю, что когда вы откроете терминал и введете env, вы увидите много переменных окружения; Одним из наиболее важных из них является PATH. Задание cron не входит в систему, так что файлы.profile не выполняются. Таким образом, в вашем скрипте вы должны установить или дополнить переменные среды, такие как PATH.
Кроме того, запись cron не должна использовать ~, но указывать полный путь.

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

HOME=/home/willem
LANG=en_US.UTF-8
LC_ADDRESS=nl_NL.UTF-8
LC_IDENTIFICATION=nl_NL.UTF-8
LC_MEASUREMENT=nl_NL.UTF-8
LC_MONETARY=nl_NL.UTF-8
LC_NAME=nl_NL.UTF-8
LC_NUMERIC=nl_NL.UTF-8
LC_PAPER=nl_NL.UTF-8
LC_TELEPHONE=nl_NL.UTF-8
LC_TIME=nl_NL.UTF-8
LOGNAME=willem
PATH=/usr/bin:/bin
PWD=/home/willem
SHELL=/bin/sh
SHLVL=1
_=/usr/bin/env

Proper scripts start with a shebang expression, some text explaining what the script will do (you might forget after a few months) and then setting environment variables. A small example (NB willem is my user name:

#!/bin/bash    # Script is created and tested for Bash.
# Example script Hello, runs outside a terminal so PATH is minimal.
# We must set env vars.
# Note I do not use "export PATH=$PATH:..." etc, because I want my progs
# directory to be found first.
export MYHOME=/home/willem
export MYLOGS=$MYHOME/logs
export MYPROGS=$MYHOME/prog
export PATH=$MYPROGS:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
#
# The main code of the script:
#
echo "Hello: started" > $MYLOGS/Hello.log
goodDay >> $MYLOGS/Hello.log   # goodDay is also in $MYPROGS
...
...
#EOF

To put the script in cron, enter crontab -e:
You are in vi so go to end of file and add:
* * * * * /home/willem/prog/Hello

Close and save, and view your crontab entry/entries: crontab -l

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