python:将脚本工作目录更改为脚本自己的目录
我每分钟从crontab运行一个python shell:
* * * * * /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
失败。
有没有一种很好的方法来告诉脚本将工作目录更改为脚本自己的目录? 我会喜欢一个可以用于任何脚本位置的解决scheme,而不是明确地告诉脚本它在哪里。
编辑:
os.chdir(os.path.dirname(sys.argv[0]))
是最简洁优雅的解决scheme。 感谢您的回答和解释!
这将改变你的当前工作目录,以便打开相对path将工作:
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)
这需要脚本的文件名,将其转换为绝对path,然后提取该path的目录,然后更改为该目录。
你可以通过使用sys.path[0]
来获得更短的版本。
os.chdir(sys.path[0])
从http://docs.python.org/library/sys.html#sys.path
在程序启动时被初始化,这个列表的第一个项目
path[0]
是包含用来调用Python解释器的脚本的目录
不要这样做。
你的脚本和你的数据不应该被整合到一个大目录中。 把你的代码放在一些已知的位置( site-packages
或者/var/opt/udi
或者其他)与你的数据分开。 在你的代码上使用好的版本控制,以确保你有当前和以前的版本相互分离,所以你可以回到以前的版本和testing未来的版本。
底线:不要混淆代码和数据。
数据是宝贵的。 代码来来去去。
提供工作目录作为命令行参数值。 你可以提供一个默认的环境variables。 不要推论(或猜测)
使其成为必需的参数值并执行此操作。
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作为单个命令执行的子shell。 || exit 1
|| exit 1
导致您的cronjob在目录不可用的情况下失败。
虽然其他解决scheme对于特定的脚本来说可能会更加优雅,但在无法修改要执行的程序或命令的情况下,我的示例仍然有用。