python:将脚本的工作目录更改为脚本所在目录
我每分钟通过定时任务(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
时就失败了。
有没有简单的方法可以让脚本把工作目录切换到它自己所在的目录?我希望这个解决方案能适用于任何脚本的位置,而不是明确告诉脚本它在哪里。
5 个回答
别这么做。
你的脚本和数据不应该混在一个大文件夹里。把你的代码放在一个固定的位置(比如 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 )
不要根据软件的位置“假设”一个目录。长远来看,这样做不会有好结果。
你可以通过使用 sys.path[0]
来获取一个更短的版本。
os.chdir(sys.path[0])
来自 http://docs.python.org/library/sys.html#sys.path
在程序启动时初始化的这个列表的第一个项目,
path[0]
,是包含用于启动Python解释器的脚本的目录。
这段代码会把你当前的工作目录改成这样,这样打开相对路径的时候就能正常工作了:
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)
这个过程会获取你脚本的文件名,把它转换成一个绝对路径,然后提取出这个路径的目录,最后切换到那个目录。