python:スクリプトの作業ディレクトリをスクリプト自身のディレクトリに変更します
-
07-07-2019 - |
質問
毎分crontabからPythonシェルを実行します:
* * * * * /home/udi/foo/bar.py
/ home / udi / foo
には、 / home / udi / foo / log
や / home / udi / foo / config <などの必要なサブディレクトリがあります。 / code>、
/home/udi/foo/bar.py
が参照します。
問題は、 crontab
が別の作業ディレクトリからスクリプトを実行するため、 ./ log / bar.log
を開こうとすると失敗することです。
作業ディレクトリをスクリプト自身のディレクトリに変更するようにスクリプトに指示する良い方法はありますか?スクリプトの場所を明示的に伝えるのではなく、任意のスクリプトの場所で機能するソリューションを探しています。
編集:
os.chdir(os.path.dirname(sys.argv[0]))
最もコンパクトでエレガントなソリューションでした。回答と説明をありがとう!
解決
これにより、現在の作業ディレクトリが変更され、相対パスを開くことができるようになります。
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)
これは、スクリプトのファイル名を取得し、絶対パスに変換し、そのパスのディレクトリを抽出して、そのディレクトリに変更します。
他のヒント
sys.path [0]
を使用して、より短いバージョンを取得できます。
os.chdir(sys.path[0])
http://docs.python.org/library/sys.htmlから#sys.path
プログラムの起動時に初期化される、このリストの最初の項目、
path [0]
は、次の目的で使用されたスクリプトを含むディレクトリです。 Pythonインタープリターを呼び出します
これをしないでください。
スクリプトとデータを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 )
「想定」しないでくださいソフトウェアの場所に基づいたディレクトリ。長期的にはうまくいきません。
crontabコマンドを次のように変更します
* * * * * (cd /home/udi/foo/ || exit 1; ./bar.py)
(...)
は、crondが単一のコマンドとして実行するサブシェルを開始します。 || exit 1
を使用すると、ディレクトリが使用できない場合にcronjobが失敗します。
他のソリューションは、特定のスクリプトの長期的にはよりエレガントかもしれませんが、私の例は、実行したいプログラムやコマンドを変更できない場合に役立ちます。