CRONが正しいPATHを呼び出すようにする方法


124

cronに正しいPATHを呼び出させるようにしています。シェルからPythonスクリプトを実行すると、スクリプトはbashrcに設定されたPATHを使用するため正常に実行されますが、cronを使用すると、bashrcからのすべてのPATHが使用されません。bashrcのようなcronのPATHを入力できるファイル、またはbashrcからPATHを呼び出す方法はありますか?

申し訳ありませんが、私はこれを正しく言っていないと思います。正しいスクリプトを実行できます(つまり、crontabのスクリプトへのPATHはここでは問題ではありません)。そのスクリプトが実行されているときにビルドを実行すると、これはで設定され.bashrcたパス。ログイン時にスクリプトを実行すると、.bashrcPATHが取得されます。cronはシェルで実行されないため、取得されません.bashrc。bashスクリプトラッパーを記述せずにこれを取り込む方法はありますか?


cronジョブのために仕事にbashrcに設定を取得する方法については、ここで与えられた提案を見てもを持っている:stackoverflow.com/q/15557777/1025391を
moooeeeep

2
現在の環境にプロファイルを含める魔法のシンプルで正しいコマンドはですsource /etc/profile。これは、.bashrc他の多くの潜在的に欠落しているものを食べてしまうはずです。あなたには、いくつかのスクリプトは、「スタンドアロン」を実行したい場合は、明示的なプロファイルの調達はかなり便利な取得、それはまた、奇妙な環境から保護し、そう...
エクサ

1
@exa +100これによりsh、crontabによって呼び出されるスクリプトが機能します。のようなジョブを追加し、* * * * * echo $PATH > ~/crontab_path.txt1分後にファイルを確認することで、パスが更新されたことを確認できます。
ジオセオリー2015年

回答:


177

使用しました/etc/crontab。私はviこのファイルに必要なPATH を使用して入力し、ルートとして実行しました。通常のcrontabは、設定したPATHを上書きします。これを行う方法についての良いチュートリアル

システム全体のcronファイルは次のようになります。

This has the username field, as used by /etc/crontab.
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file.
# This file also has a username field, that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user   command
42 6 * * *   root    run-parts --report /etc/cron.daily
47 6 * * 7   root    run-parts --report /etc/cron.weekly
52 6 1 * *   root    run-parts --report /etc/cron.monthly
01 01 * * 1-5 root python /path/to/file.py

17
これはユーザーレベルでcrontab -eと連動し、その方法でも安全です。
Robert Brisita 2013

2
shの代わりにbashを使用できますか?
2013年

1
@chrissygormleyによって示される/ etc / crontabに設定され、また私の(Ubuntu)crontabにも設定されるデフォルトのPATHが/ etc / environmentのパスと異なることは(私には)奇妙です、特に/ sbinと/ bin // usr / sbinおよび/ usr / binの前。これを/ etc / crontabで変更して、ユーザー環境と同じにしました。
scoobydoo 2015

動作しません。cronコンテンツをファイルに出力しています。Cronが実行され、ファイルは作成されますが、コンテンツは含まれません。
Volatil3 2015

2
/etc/crontabUbuntu 14.04でrootとして実行すると、設定されたすべてのパスがcronで使用できるとは限りません。(sudo crontab -e
デビッドオリバー

50

ほとんどの場合、cronは非常に疎な環境で実行されています。次のenvようにファイルにダンプするダミージョブを追加して、cronが使用している環境変数を確認します。

* * * * * env > env_dump.txt

env通常のシェルセッションでの出力と比較してください。

独自の環境変数をローカルのcrontabの先頭に追加して、crontabの先頭で定義することができます。

$PATH現在のcrontabの先頭に追加する簡単な修正を以下に示します。

# echo PATH=$PATH > tmp.cron
# echo >> tmp.cron
# crontab -l >> tmp.cron
# crontab tmp.cron

結果のcrontabは、chrissygormleyの回答に似ていますが、crontabルールの前にPATHが定義されています。


22

フルパスをに入れる必要がありますcrontab。これが最も安全なオプションです。
そうしたくない場合は、プログラムの周りにラッパースクリプトを置き、そこにPATHを設定できます。

例えば

01 01 * * * command

になる:

01 01 * * * /full/path/to/command

また、fromから呼び出されるcronものは、それが実行するプログラムについて非常に注意する必要があり、おそらくPATH変数に独自の選択を設定します。

編集:

which <command>シェルから実行したいコマンドの場所がわからない場合は、パスが表示されます。

EDIT2:

したがって、プログラムが実行されると、最初に行うべきことは、スクリプトの実行に必要な値にPATHその他の必要な変数(などLD_LIBRARY_PATH)を設定することです。
基本的には、cron環境を変更してプログラム/スクリプトにより適したものにする方法を考える代わりに、スクリプトが起動時に適切な環境を設定することにより、スクリプトが与えられた環境を処理できるようにします。


1
パスに含まれている場合は、「whichコマンド」を使用すると、完全なパスが得られます
Paul Whelan

@Douglas Leeder-フルパスをcronに入れるとは、それをcrontabまたは別のファイルに入れるということですか?cronコマンドが「01 01 * * * command」の場合、それはどのように行うのでしょうか。ありがとう
chrissygormley

@chrissygormley-はいcrontab
ダグラスリーダー

混乱しているようです。上記の質問を書き直しました。
chrissygormley 2010年

16

私のcrontabのコマンドラインの直前にPATHを設定するとうまくいきました:

* * * * * PATH=$PATH:/usr/local/bin:/path/to/some/thing

この方法を好む。または、スクリプトの完全パスを指定します。
zw963 2017

5
PATHの新しいコピーを使用して、その実行が新しい環境になるたびに、パスが成長し続けるとは思わない
jjcf89

@ jjcf89が正しいことを確認できます。PATHは実行ごとに新しいです。
Electrovir

14

正しい値でPATH定義をユーザーのcrontabに追加すると役立ちます...私は次のように入力しました:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

そして、すべてのスクリプトを機能させるには十分です...必要に応じて、カスタムパスをそこに含めます。


1
ユーザーcrontabの場合、これが正しい答えです。システム上の誰もが編集できるわけではありません/etc/crontab。これは、ユーザーレベルで最も簡単な答えです。@Treviñoさん、よくできました。同意する場合は投票してください。
frederickjh

14

変数があなたのために働くようにしてください、これはアクセスを許可しますt

/etc/profile.d/*.shにPATHを定義します

システム全体の環境変数

/etc/profile.dディレクトリに.sh拡張子が付いたファイルは、bashログインシェルが入力されるたびに(たとえば、コンソールから、またはsshを介してログインするとき)、デスクトップセッションが読み込まれるときにDisplayManagerによって実行されます。

たとえば、ファイル/etc/profile.d/myenvvars.shを作成し、次のように変数を設定できます。

export JAVA_HOME=/usr/lib/jvm/jdk1.7.0
export PATH=$PATH:$JAVA_HOME/bin

ログインオプションでcrontabを実行してください!

CRONTAB実行スクリプトまたはコマンドと環境変数

0 9 * * * cd /var/www/vhosts/foo/crons/; bash -l -c 'php -f ./download.php'
0 9 * * * cd /var/www/vhosts/foo/crons/; bash -l -c download.sh

11

問題

スクリプトは、コンソールから実行すると機能しますが、cronでは失敗します。

原因

あなたのcrontabには正しいパス変数(そしておそらくシェル)がありません

解決

現在のシェルを追加し、crontabをパスします

あなたのためにそれを行うためのスクリプト

#!/bin/bash
#
# Date: August 22, 2013
# Author: Steve Stonebraker
# File: add_current_shell_and_path_to_crontab.sh
# Description: Add current user's shell and path to crontab
# Source: http://brakertech.com/add-current-path-to-crontab
# Github: hhttps://github.com/ssstonebraker/braker-scripts/blob/master/working-scripts/add_current_shell_and_path_to_crontab.sh

# function that is called when the script exits (cleans up our tmp.cron file)
function finish { [ -e "tmp.cron" ] && rm tmp.cron; }

#whenver the script exits call the function "finish"
trap finish EXIT

########################################
# pretty printing functions
function print_status { echo -e "\x1B[01;34m[*]\x1B[0m $1"; }
function print_good { echo -e "\x1B[01;32m[*]\x1B[0m $1"; }
function print_error { echo -e "\x1B[01;31m[*]\x1B[0m $1"; }
function print_notification { echo -e "\x1B[01;33m[*]\x1B[0m $1"; }
function printline { 
  hr=-------------------------------------------------------------------------------------------------------------------------------
  printf '%s\n' "${hr:0:${COLUMNS:-$(tput cols)}}"
}
####################################
# print message and exit program
function die { print_error "$1"; exit 1; }

####################################
# user must have at least one job in their crontab
function require_gt1_user_crontab_job {
        crontab -l &> /dev/null
        [ $? -ne 0 ] && die "Script requires you have at least one user crontab job!"
}


####################################
# Add current shell and path to user's crontab
function add_shell_path_to_crontab {
    #print info about what's being added
    print_notification "Current SHELL: ${SHELL}"
    print_notification "Current PATH: ${PATH}"

    #Add current shell and path to crontab
    print_status "Adding current SHELL and PATH to crontab \nold crontab:"

    printline; crontab -l; printline

    #keep old comments but start new crontab file
    crontab -l | grep "^#" > tmp.cron

    #Add our current shell and path to the new crontab file
    echo -e "SHELL=${SHELL}\nPATH=${PATH}\n" >> tmp.cron 

    #Add old crontab entries but ignore comments or any shell or path statements
    crontab -l | grep -v "^#" | grep -v "SHELL" | grep -v "PATH" >> tmp.cron

    #load up the new crontab we just created
    crontab tmp.cron

    #Display new crontab
    print_good "New crontab:"
    printline; crontab -l; printline
}

require_gt1_user_crontab_job
add_shell_path_to_crontab

ソース

https://github.com/ssstonebraker/braker-scripts/blob/master/working-scripts/add_current_shell_and_path_to_crontab.sh

出力例

add_curent_shell_and_path_to_crontab.sh出力例


3

私のAIXでは、cronは/ etc / environmentから環境変数を取得し、.profileに設定されているものを無視します。

編集:私はまた、さまざまな年齢のLinuxボックスをいくつかチェックアウトしましたが、これらにもこのファイルがあるように見えるため、これはおそらくAIX固有ではありません。

私はjoemallerのcron提案を使用してこれをチェックし、/ etc / environmentのPATH変数を編集する前後に出力をチェックしました。


3

さまざまな場所で同じ編集を行う必要がない場合は、おおよそ次のようにします。

* * * * * . /home/username/.bashrc && yourcommand all of your args

。スペース、次に.bashrcへのパスと&&コマンドは、環境の変更を実行中のbashシェルに取り込む魔法です。また、シェルを本当にbashにしたい場合は、crontabに次の行を含めることをお勧めします。

SHELL=/bin/bash

それが誰かを助けることを願っています!


2

cronジョブのデフォルト環境は非常に疎であり、Pythonスクリプトを開発する環境とは大きく異なる場合があります。cronで実行される可能性があるスクリプトの場合、依存する環境は明示的に設定する必要があります。cronファイル自体に、Python実行可能ファイルとPythonスクリプトへの完全パスを含めます。


2

これはすでに回答されていることは知っていますが、彼にとっては役立つと思います。私が最近解決した同様の問題があり(ここにあります)、この質問に回答するために実行した手順のハイライトを以下に示します。

  1. スクリプトが動作することを確認するためにスクリプトをテストするシェルの.profileまたは.bash_profile内のPYTHONPATH(こことここ、および詳細はここにあります)に必要な変数があることを確認してください。

  2. crontabを編集して、cronジョブでスクリプトを実行するために必要なディレクトリを含めます(こことここにあります)

    a)ここで説明するように、PATHディレクトリ(。)にルートディレクトリを含めるようにしてください(基本的に、コマンドで実行可能ファイルを実行している場合は、ルートまたは実行可能ファイルが格納されているディレクトリを見つける必要があります)およびおそらくこれら(/ sbin:/ bin:/ usr / sbin:/ usr / bin)

  3. crontabファイルで、以前にスクリプトを正常に実行したディレクトリ(つまり、Users / user / Documents / foo)にディレクトリを変更するcronjobを作成します。

    a)これは次のようになります。

    * * * * cd /Users/user/Documents/foo; bar -l doSomething -v 
    

2

@トレビノ:あなたの答えは私が私の問題を解決するのに役立ちました。ただし、初心者にとっては、段階的にアプローチすることを試みます。

  1. Javaの現在のインストールを取得する $ echo $JAVA_HOME
  2. $ crontab -e
  3. * * * * * echo $PATH-これにより、現在crontabで使用されているPATH値を把握できます。crontabを実行し、crontabで使用される$ PATH値を取得します。
  4. 次に、crontabを再度編集して、目的のJava binパスを設定しますcrontab -e。b)PATH=<value of $JAVA_HOME>/bin:/usr/bin:/bin(そのサンプルパス); c)今のようなあなたのスケジュールされたジョブ/スクリプト*/10 * * * * sh runMyJob.sh &; d)echo $PATH現在は不要なので、crontabから削除します。

2

cronに必要なPATHを設定します

crontab -e

編集:押す i

PATH=/usr/local/bin:/usr/local/:or_whatever

10 * * * * your_command

保存して終了 :wq


1

私が見つけた最も簡単な回避策は次のようになります。

* * * * * root su -l -c command

この例ではsu、rootユーザーとして起動し、ユーザーの完全な環境($ PATHを含む)を、ログインしたかのように設定してシェルを起動します。別のディストリビューションでも同じように機能し、.bashrc(例)またはセットアップツールを提供していて、ユーザーのシステムのディストリビューションやファイルレイアウトがわからない場合に問題になる可能性がある特定のパスをハードコーディングすることを避けます。

surootとは別のユーザーが必要な場合は、後でユーザー名を指定することもできますが、指定したユーザーに切り替えるための十分な権限があることを確認できるため、コマンドのroot前にパラメーターを残す必要があります。susu


-3

使用する必要があるのはwebminPATH値を設定する手順です。

System
  -> Scheduled Cron Jobs
       -> Create a new environment variable
            -> For user: <Select the user name>
            -> Variable name: PATH
            -> Value: /usr/bin:/bin:<your personal path>
            -> Add environment variable: Before all Cron jobs for user
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.