Por que esse cronjob não funciona?

1

Atualmente, estou tentando configurar um cron job com um script python que eu tenha git clonado de aqui . A hierarquia para acessar meu script pode ser descrita abaixo:

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

Agora isso funciona quando eu uso o comando python change_wallpaper_reddit.py --time new dentro da pasta Daily_Reddit_Wallpapers . No entanto, quando eu tento o comando, * * * * * python ./change_wallpaper_reddit.py --time new , recebo o erro:

change_wallpaper_reddit.py: command not found

Quando tento invocar * * * * * python ~/Daily-Reddit-Wallpaper/change_wallpaper_reddit.py , obtenho:

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')

Eu não entendo porque isso acontece.

    
por Sharan Duggirala 03.05.2017 / 22:32

2 respostas

2

O problema é que o script não foi projetado para funcionar com o Cron. Ele usa poucas variáveis de ambiente, que não são acessíveis a partir do Cron e são diferentes, dependendo do ambiente de área de trabalho do usuário atual. Esta é a razão na qual a página pode ser descrita como outra forma de executar na inicialização . Mas é possível definir valores dessas variáveis enquanto o CronJob estiver sendo executado.

Por exemplo, quando é o ambiente de desktop padrão do Ubuntu, as palavras-chave de pesquisa devem se tornar: 'gsettings' e 'cron', então nossa pesquisa nos levará a tópicos com fio como: Background não está mudando usando gsettings do cron , onde podemos encontrar explicações adicionais como:

  

Se você executar o script a partir do seu próprio ambiente (por exemplo, de um terminal   janela ou a partir de aplicativos de inicialização), um número de ambiente   variáveis serão definidas. cron , no entanto, executa seu script com um limite   conjunto de variáveis de ambiente.

     

Para editar gsettings com sucesso de cron , você precisa definir o    DBUS_SESSION_BUS_ADDRESS variável de ambiente. Você pode fazer isso   adicionando duas linhas ao seu script, conforme descrito aqui ...

Executar: Diário-Reddit-Wallpaper através do Cron via script de inicialização

Aqui, criaremos um script de inicialização, que definirá as variáveis de ambiente necessárias, dependendo do ambiente de área de trabalho escolhido (por um argumento).

1. Primeiro clonado Daily-Reddit-Wallpaper e também instala as dependências:

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. Crie o arquivo de script - change_wallpaper_reddit.sh :

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

O conteúdo do script é:

#!/bin/sh

# Reference: https://askubuntu.com/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 [ "" != "$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} ] || [ "" = "gnome" ] || [ "" = "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 [ "" = "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 [ "" = "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 [ "" = "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 &&  ~ /tty[0-9]+/ {print ; exit}')

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

elif [ "" = "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://sobrelinux.info/questions/19093/xubuntu-how-to-set-the-wallpaper-using-the-command-line"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 "" > "$HOME/$SHOME/last-desktop-environment.log"

Este script tem um argumento , que determina seu comportamento dependendo do ambiente de área de trabalho escolhido (de você) (DE). Os valores possíveis são:

  • gnome ou unity ou empty (padrão) - quando você usa o DE padrão do Ubuntu;
  • kde - quando você usa o KUbuntu DE;
  • lxde - quando você usa LUbuntu DE;
  • mate - quando você usa o Ubuntu MATE DE;
  • xfce4 - quando você usa o XUbuntu DE.

Você também pode personalizar esses parâmetros iniciais:

  • SHOME= define a pasta onde o Daily-Reddit-Wallpaper está localizado no seu sistema.
  • DIR= define a pasta de saída no diretório inicial para salvar os Papéis de parede - o valor padrão ( Pictures/Wallpapers ) é usado no script acima.
  • TIME= define o valor do parâmetro --time de change_wallpaper_reddit.py .

3. Crie CronJob ( crontab -e ), que executa change_wallpaper_reddit.sh (a cada hora, por exemplo):

  • Se você usar o DE padrão do Ubuntu, este CronJob pode ser:

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

    também esta sintaxe trará o mesmo resultado:

    0 * * * * /home/<your user name>/Daily-Reddit-Wallpaper/change_wallpaper_reddit.sh gnome > /home/<your user name>/Daily-Reddit-Wallpaper/cron.log 2>&1
    
  • Se você usa o KUbuntu DE, por exemplo, este CronJob pode ser:

    0 * * * * /home/<your user name>/Daily-Reddit-Wallpaper/change_wallpaper_reddit.sh kde > /home/<your user name>/Daily-Reddit-Wallpaper/cron.log 2>&1
    
  • Para a solução de problemas, verifique o arquivo de log: cat /home/$USER/Daily-Reddit-Wallpaper/cron.log

Voilà. Está funcionando!

Referências e reding adicional:

por pa4080 04.05.2017 / 21:57
4

Por favor, esteja ciente de que o cronjab é executado em um shell que possui uma configuração de ambiente limitada. Com isso quero dizer que quando você abre um terminal e digita env você verá muitas variáveis de ambiente; um dos mais importantes é o PATH. O cron job não faz login, por assim dizer, os arquivos .profile não são executados. Portanto, no seu script, você deve definir ou complementar variáveis de ambiente, como o PATH.
Além disso, uma entrada cron não deve usar o ~ mas colocar o caminho completo.

No meu sistema, criei um pequeno script para listar as variáveis de ambiente que são definidas quando o script é iniciado no cron. Como você vê muito menos do que quando em um terminal:

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

Os scripts apropriados começam com uma expressão shebang, algum texto explicando o que o script fará (você pode esquecer depois de alguns meses) e depois configurando variáveis de ambiente. Um pequeno exemplo (NB willem é o meu nome de usuário:

#!/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

Para colocar o script no cron, digite crontab -e :
Você está em vi , então vá até o final do arquivo e adicione:
    * * * * * / home / willem / prog / Hello

Feche e salve e visualize as entradas / entradas do crontab: crontab -l

    
por user680858 04.05.2017 / 01:06