2013-07-11 12 views
6

を呼び出すのcrontabで実行していない私は、cronジョブでsciptsが原因のcron内殻の開口部に、スクリプト自体の内部で実行するために必要な環境変数を維持する必要があることを詳述複数の投稿と多くの記事を読みました。私の状況は、私のパス変数がすべて説明されているように設定されているという点で独特で、subprocess.call()を使ってPythonの卵を呼び出すことに成功しますが、そこから崩壊するようです。これにより、プロセス全体がcronジョブで中断されます。のPythonスクリプトpysaunter

は明確にするために、ここで私はを参照してください。手順は次のとおりです。

1) cronjob calls run_test.py -n foo 
2) run_test.py sets the environment variables correctly 
(cur_shell_path=sys.path (converted to proper path string, not shown here) 
my_env= os.environ.copy() 
my_env["PATH"] = my_env["PATH"] + cur_shell_path) 
3) run_test.py calls subprocess.call("pysaunter -m foo -v", env=my_env, shell=True) 
ステップ3の出力は、それが卵を見つけることに成功しpysaunterから必要なモジュールをロードするために開始しますが、それは時に壊れていることを示している

pysaunterを変更するためのディレクトリを探しようとしています。エラーが表示されます:

ImportError: no module named helpers 

このパスを環境に複数回追加しようとしましたが、helpers.pyを含むディレクトリが見つからないようです。コマンドpysaunter -m foo -vは、対話型シェルから呼び出されたときに正常に動作します。

私はpysaunterに多くの助けを見つけることができなかったので、私はあまりpysaunterの詳細はここでは不必要なことであろうと想定しています。ピサウンタについてもっと知っていれば、もっと情報が必要な場合は教えてください。私は何を共有するか分からない。

私はまたの.profile/.bash_profileのを編集することで、シェルのデフォルトの動作を変更する機能を議論する多くの記事を読みました。パス変数をグローバルにアクセス可能にする場所を見つけようとしましたが、何も見つかりませんでした。私はこれがどのように行われているのか分からず、問題を解決するかもしれないので、それについて何か知っていれば教えてください。

最終的に、これはMac 10.7.5で動作しています。

答えて

3

PYTHONPATH使用し、多くの、多くのstackoverflow.comの記事およびその他のチュートリアル私が見つけたPerlスクリプトの助けを借りて、これを似たようにして、これを動作させるために何が必要なのかを知ることができました。ここで

は、すべてが正しく設定されているか確認することに手順は次のとおりです。

  1. あなたはPYTHONPATHで必要な変数を持っていることを確認します(herehereを見つけ、詳細はhereを行く。)の内部スクリプトをテストして、動作することを確認したいシェルの.profileまたは.bash_profile。(herehereを発見した)cronジョブであなたの スクリプトを実行するために必要なディレクトリを含むように

  2. を編集しますのcrontab。

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

  3. crontabファイルで、現在のディレクトリをスクリプトを正常に実行したディレクトリ(たとえば、/ Users/user/Documents/foo)に変更するcronジョブを作成します。

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

    * * * * cd /Users/user/Documents/foo; bar -l doSomething -v 
    
  4. 私の問題は、実行可能ファイルを呼び出すと特異的に扱っているので、実行するPythonスクリプトを書くの複数の方法があることに注意する必要がある(ただし発見の過程で、私はcronのサブプロセスを使って行われた呼び出しでこれが動作することを学びました)。

    第1の方法は次のようになります。

    ... #some script calls 
    my_env = os.environ.copy() 
    my_env["PYTHONPATH"] = "{}:{}".format(os.environ["PATH"] ,"<path you want to include>") 
    os.chdir("<path/to/desired/directory>") 
    subprocess.Popen(<call_as_string>, env=my_env, shell=True) 
    

    そして第二には、次のようになります。実行ファイルは、それが呼ばれたシェルに含まヘルパーディレクトリへのパスを必要とするので

    ... #some script calls 
    os.environ["PYTHONPATH"] = "{}:{}".format(os.environ["PATH"] ,"<path you want to include>") 
    os.chdir("<path/to/desired/directory>") 
    subprocess.Popen(<call_as_list_of_arguments) 
    

    から、説明したように実行可能ファイルに環境変数を渡す必要がありましたhere。私が見つけたのは、環境内のPATH変数を変更してもcronジョブでは機能しませんでしたが、PYTHONPATHを設定していたことです。私はhereを読んでいます。PATH変数はシェルが実行可能ファイルだけを探すために使用されるので、新しいシェルをcronjobに入れるには、新しいPythonモジュールを探すためにシェルにPYTHONPATHを渡す必要があります。 (これはまたexplained in the Python docsである。)は、2つの異なる方法の間

    差が問題に引用されたサブプロセスのドキュメントで説明されているが、このモジュール上の良好なチュートリアルhere見出すことができます。

1

あなたが言ったことは意味をなさない。

あなたはshell_env = sys.pathと言っています。 sys.pathは、Pythonが環境変数マッピングではなくモジュールを探すためのフォルダのリストです!

それをsubprocess.callに使用します。おそらく、あなたはenv=my_envと書くことを意図していました。

これは次の問題です。まず、PATHは、':'で区切られたフォルダのリストにする必要があります。 shell_pathを最後のフォルダに固定するだけです。

最後に、Pythonは多くの試行錯誤の後(。あなたが持っているものの問題であるように思われた)Pythonモジュールを見つけるためにリストとして

+1

私の問題を指摘していただきありがとうございます。私は今、my_envが渡されていることを示すために修正しました。また、Unixベースのマシンでは、コロン(:)を使用してパス値を区切るため、問題になることはありません。最後に、Pythonpathはローカルディレクトリを検索するために使われます。ローカルディレクトリは、Unixではシェルがどこから起動されたかによって定義されます(http://docs.python.org/release/1.5.1p1/tut/searchPath.html)。 cronジョブは、正しいディレクトリから起動されず、.profileまたは.bash_profileを読み込まない非対話型シェルを呼び出すので、パスは追加されないため、Pythonpathは設定されません。 – derigible

+1

あなたはコロンについて正しいです。私はそれを修正した。 cronジョブでPYTHONPATHを設定する必要があります。 PYTHONPATHを目的のディレクトリに設定し、Pythonスクリプトを呼び出すラッパースクリプトを作成することができます。 – korylprince