web-dev-qa-db-ja.com

このcronjobが機能しないのはなぜですか?

現在、 here からgitクローンを作成したpythonスクリプトでcron jobをセットアップしようとしています。スクリプトに到達する階層は、次のように説明できます。

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

これが起こる理由がわかりません。

1

問題は、スクリプトがCronで動作するように設計されていないことです。 Cronからアクセスできないいくつかの環境変数を使用し、現在のユーザーのデスクトップ環境によって異なります。これが、起動時に実行する 別の方法 で説明するページの理由です。ただし、CronJobの実行中にこれらの変数の値を設定することは可能です。

たとえば、デフォルトのUbuntuのデスクトップ環境の場合、検索キーワードは「gsettings」と「cron」になります。検索すると、次のような有線トピックにつながります: 、ここで追加の説明を見つけることができます:

独自の環境(たとえば、ターミナルウィンドウまたはスタートアップアプリケーション)からスクリプトを実行すると、多くの環境変数が設定されます。 cronただし、限られた環境変数セットでスクリプトを実行します。

gsettingsからcronを正常に編集するには、DBUS_SESSION_BUS_ADDRESS環境変数を設定する必要があります。 here ...で説明されているように、スクリプトに2行追加することでそれを行うことができます。


実行:起動スクリプトを介してCronを介してDaily-Reddit-Wallpaper

ここでは、選択された(引数により)デスクトップ環境に応じて必要な環境変数を設定するスタートアップスクリプトを作成します。

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://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"

このスクリプトには1つの argument$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=は、--timechange_wallpaper_reddit.pyパラメーターの値を設定します。

作成CronJobcrontab -e)、change_wallpaper_reddit.shを実行します(たとえば、1時間ごとに)。

  • デフォルトの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

Voilà。それは機能しています!


参照とさらなるレディング:

2
pa4080

Cronjabは、環境設定が制限されているシェルで実行されることに注意してください。つまり、ターミナルを開いてenvと入力すると、多くの環境変数が表示されます。最も重要なものの1つは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

適切なスクリプトは、Shebang式で始まり、スクリプトの動作を説明するテキスト(数か月後に忘れる場合があります)を実行し、環境変数を設定します。小さな例(NB willemは私のユーザー名です:

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

スクリプトをcronに入れるには、crontab -e
あなたはviにいるので、ファイルの最後に移動して以下を追加します。
* * * * */home/willem/prog/Hello

閉じて保存し、crontabエントリ/エントリを表示します。crontab -l

4
user680858