206

毎分 crontab から Python シェルを実行します。

* * * * * /home/udi/foo/bar.py

/home/udi/foo/home/udi/foo/logや など/home/udi/foo/config、必要なサブディレクトリがいくつかあり/home/udi/foo/bar.pyます。

問題はcrontab、別の作業ディレクトリからスクリプトを実行するため、開こうとすると./log/bar.log失敗することです。

作業ディレクトリをスクリプト自身のディレクトリに変更するようにスクリプトに指示する良い方法はありますか? スクリプトの場所を明示的に伝えるのではなく、任意のスクリプトの場所で機能するソリューションが欲しいと思います。

編集:

os.chdir(os.path.dirname(sys.argv[0]))

最もコンパクトでエレガントなソリューションでした。あなたの答えと説明をありがとう!

4

4 に答える 4

254

これにより、現在の作業ディレクトリが次のように変更され、相対パスを開くことが機能します。

import os
os.chdir("/home/udi/foo")

ただし、スクリプトを作成しているときにどのディレクトリになるかわからない場合でも、Python スクリプトが配置されているディレクトリに変更する方法を尋ねました。これを行うには、次のos.path関数を使用できます。

import os

abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
os.chdir(dname)

これは、スクリプトのファイル名を受け取り、それを絶対パスに変換し、そのパスのディレクトリを抽出して、そのディレクトリに変更します。

于 2009-09-16T13:26:24.527 に答える
54

を使用して短いバージョンを取得できますsys.path[0]

os.chdir(sys.path[0])

http://docs.python.org/library/sys.html#sys.pathから

プログラムの起動時に初期化されるため、このリストの最初の項目である path[0]は、Python インタープリターを呼び出すために使用されたスクリプトを含むディレクトリです。

于 2012-02-03T14:41:28.983 に答える
26

これをしないでください。

スクリプトとデータを 1 つの大きなディレクトリにマッシュアップしないでください。コードをデータとは別の既知の場所 (site-packagesまたは/var/opt/udi何か) に配置します。コードの適切なバージョン管理を使用して、現在のバージョンと以前のバージョンが互いに分離されていることを確認し、以前のバージョンにフォールバックして将来のバージョンをテストできるようにします。

結論: コードとデータを混同しないでください。

データは貴重です。コードは行ったり来たりします。

コマンドライン引数値として作業ディレクトリを指定します。環境変数としてデフォルトを指定できます。推測しないでください(または推測しないでください)

これを必須の引数値にして、これを行います。

import sys
import os
working= os.environ.get("WORKING_DIRECTORY","/some/default")
if len(sys.argv) > 1: working = sys.argv[1]
os.chdir( working )

ソフトウェアの場所に基づいてディレクトリを「想定」しないでください。長期的にはうまくいきません。

于 2009-09-16T13:34:21.243 に答える
23

crontab コマンドを次のように変更します。

* * * * * (cd /home/udi/foo/ || exit 1; ./bar.py)

(...)、crond が単一のコマンドとして実行するサブシェルを開始します。これ|| exit 1により、ディレクトリが利用できない場合に cronjob が失敗します。

他のソリューションは、特定のスクリプトに対して長期的にはより洗練されているかもしれませんが、私の例は、実行したいプログラムやコマンドを変更できない場合にも役立ちます。

于 2013-01-31T14:37:45.753 に答える