web-dev-qa-db-fra.com

Pourquoi ce travail ne fonctionne-t-il pas?

J'essaie actuellement de configurer un cron job avec un script python à partir duquel j'ai été cloné ici . La hiérarchie pour atteindre mon script peut être décrite comme suit:

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

Cela fonctionne maintenant lorsque j'utilise la commande python change_wallpaper_reddit.py --time new dans le dossier Daily_Reddit_Wallpapers. Cependant, lorsque j'essaie la commande * * * * * python ./change_wallpaper_reddit.py --time new, j'obtiens le message d'erreur suivant:

change_wallpaper_reddit.py: command not found

Lorsque j'essaie d'appeler * * * * * python ~/Daily-Reddit-Wallpaper/change_wallpaper_reddit.py, je reçois:

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

Je ne comprends pas pourquoi cela se produit.

1

Le problème est que le script n'est pas conçu pour fonctionner avec Cron. Il utilise peu de variables d’environnement, qui ne sont pas accessibles depuis Cron et qui sont différentes, en fonction de l’environnement de bureau de l’utilisateur actuel. C'est la raison sur sa page pour être décrit une autre façon pour s'exécutant au démarrage . Mais il est possible de définir les valeurs de ces variables pendant l'exécution de CronJob.

Par exemple, lorsqu'il s'agit de l'environnement de bureau par défaut d'Ubuntu, les mots clés de la recherche doivent devenir: "gsettings" et "cron". Notre recherche nous mènera ensuite à des sujets câblés tels que: l'arrière-plan ne change pas à l'aide de gsettings de cron , où nous pourrions trouver des explications supplémentaires comme:

Si vous exécutez le script à partir de votre propre environnement (par exemple, à partir d’une fenêtre de terminal ou d’applications de démarrage), un certain nombre de variables d’environnement seront définies. cron cependant exécute votre script avec un ensemble limité de variables d’environnement.

Pour modifier gsettings à partir de cron, vous devez définir la variable d’environnement DBUS_SESSION_BUS_ADDRESS. Vous pouvez le faire en ajoutant deux lignes à votre script, comme décrit ici ...


Exécuter: Daily-Reddit-Wallpaper via Cron via un script de démarrage

Ici, nous allons créer un script de démarrage, qui définira les variables d’environnement nécessaires en fonction de l’environnement de bureau choisi (par un argument).

1. cloné en premier Daily-Reddit-Wallpaper et installez également les dépendances :

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. Créez le fichier 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

Le contenu du script est:

#!/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 [ "$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://askubuntu.com/q/380550/566421 and https://askubuntu.com/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"

Ce script a un argument$1, qui détermine son comportement en fonction de l'environnement de bureau choisi (par vous). Les valeurs possibles sont:

  • gnome ou unity ou empty (valeur par défaut) - lorsque vous utilisez la valeur par défaut Ubuntu DE;
  • kde - lorsque vous utilisez KUbuntu DE;
  • lxde - lorsque vous utilisez LUbuntu DE;
  • mate - lorsque vous utilisez Ubuntu MATE DE;
  • xfce4 - lorsque vous utilisez XUbuntu DE.

Aussi, vous pouvez personnaliser ces paramètres initiaux:

  • SHOME= définissez le dossier où Daily-Reddit-Wallpaper se trouve dans votre système.
  • DIR= définissez le dossier de sortie du répertoire de base dans lequel enregistrer les fonds d'écran. La valeur par défaut (Pictures/Wallpapers) est utilisée dans le script ci-dessus.
  • TIME= définit la valeur du paramètre --time de change_wallpaper_reddit.py.

3. Créez CronJob (crontab -e), qui exécute change_wallpaper_reddit.sh (à chaque heure par exemple):

  • Si vous utilisez le DE par défaut Ubuntu, ce CronJob pourrait être:

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

    aussi cette syntaxe apportera le même résultat:

    0 * * * * /home/<your user name>/Daily-Reddit-Wallpaper/change_wallpaper_reddit.sh gnome > /home/<your user name>/Daily-Reddit-Wallpaper/cron.log 2>&1
    
  • Si vous utilisez KUbuntu DE, par exemple, ce CronJob pourrait être:

    0 * * * * /home/<your user name>/Daily-Reddit-Wallpaper/change_wallpaper_reddit.sh kde > /home/<your user name>/Daily-Reddit-Wallpaper/cron.log 2>&1
    
  • Pour le dépannage, consultez le fichier journal: cat /home/$USER/Daily-Reddit-Wallpaper/cron.log

Voilà. ça marche!


Références et reding:

2
pa4080

Veuillez noter qu'un cronjab s'exécute dans un shell dont la configuration de l'environnement est limitée. J'entends par là que lorsque vous ouvrez un terminal et entrez env, vous verrez beaucoup de variables d'environnement. L'un des plus importants est PATH. Le travail cron ne se connecte pas pour ainsi dire, les fichiers .profile ne sont donc pas exécutés. Donc, dans votre script, vous devez vous assurer de définir ou de compléter des variables d'environnement telles que PATH.
De plus, une entrée cron ne devrait pas utiliser le ~ mais mettre le chemin complet.

Dans mon système, j'ai créé un petit script pour répertorier les variables d'environnement définies lors du démarrage du script dans cron. Comme vous le voyez beaucoup moins que dans un 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
_

Les scripts appropriés commencent par une expression Shebang, un texte expliquant ce que le script fera (vous pourriez oublier au bout de quelques mois), puis définissez des variables d'environnement. Un petit exemple (NB willem est mon nom d'utilisateur:

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

Pour mettre le script dans cron, entrez crontab -e:
Vous êtes dans vi alors allez en fin de fichier et ajoutez:
* * * * */home/willem/prog/Hello

Fermez et enregistrez, et affichez votre/vos entrée (s) dans la crontab: crontab -l

4
user680858