通过Cron从目录运行程序
我在一台使用UNIX的OSX电脑上。我有一个Python程序想要每小时运行一次,所以我在编辑器里设置了一个简单的定时任务命令:
0 * * * * python Documents/workspace/programfolder/src/ProgramToRun.py
不过我还没实际尝试过,因为我已经遇到了一些问题。我试着从我的家目录直接运行这个命令 python Documents/workspace/programfolder/src/ProgramToRun.py
,但脚本找不到它依赖的任何文件。就好像这个程序在我的家目录里运行,找不到它需要的文件。如果我进入程序所在的文件夹,然后运行 python ProgramToRun.py
,那就没问题。所以我的问题是,如何让定时任务(cron)把这个程序当作是在它的目录下运行呢?我给的这个目录路径能用吗,还是需要给一个更绝对的路径,比如 /Users/MyName...等等?
4 个回答
在OS X上,正如文档所说:
虽然
cron
仍然被支持,但不推荐使用。它已经被launchd
取代。
如果你对cron
非常熟悉,比如你有丰富的Unix经验,或者你在OS X和Linux上都在做同样的事情,或者你有其他合理的理由,那你可以继续使用cron
。但显然,这里并不是这种情况。
如果你使用的是launchd
,那么这里的答案就简单多了。从手册页面来看:
WorkingDirectory <string>
这个可选的键用于指定在运行任务之前要切换到的目录。
或者,如果你想修改运行应用程序时使用的环境(例如,把它的目录放入PYTHONPATH
),这也很简单。
下面是一个每小时运行你的程序的launchd.plist
文件示例:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.example.ProgramToRun</string>
<key>ProgramArguments</key>
<array>
<string>python</string>
<string>Documents/workspace/programfolder/src/ProgramToRun.py</string>
</array>
<key>StartInterval</key>
<integer>3600</integer>
<key>WorkingDirectory</key>
<string>Documents/workspace/programfolder/src/</string>
</dict>
</plist>
很多老的Unix用户看到这个会说:“哇,这真是太啰嗦了。”我同意。不过,它并没有被淘汰。而且,它有额外的功能,与休眠的交互也有很好的文档说明,配置起来也很简单等等。而且,苹果的文档中有很多示例和解释会告诉你如何让这个工作,而cron
几乎只有手册和一些说“如果你知道自己在做什么,那就用吧,但我们不会帮你”的文件。
在你开始做相对路径相关的操作之前,把这个放在你脚本的最上面。
import os
scriptdir = os.path.dirname(os.path.abspath(__file__))
os.chdir(scriptdir)
这也可能说明你的脚本根本没有尝试根据脚本的位置来解析路径等。脚本不应该依赖用户从与脚本相同的目录运行它。
我通常会使用 scriptdir
来找到与脚本相关的东西,比如:
open(os.path.join(scriptdir, 'data', 'someconfig.cfg'))
,而不是 open(os.path.join('data', 'someconfig.cfg'))
你可以用两种方法来做到这一点:
第一种方法:
先进入包含Python脚本和依赖文件的文件夹,然后从那里运行脚本,具体操作如下:
(cd /Users/username/Documents/workspace/programfolder/src/ && python ProgramToRun.py)
这里的括号表示一个“子进程”。可以把它想象成一个连续的会话,所有命令都会在这个会话中运行。&&
的作用类似于;
,但如果前一个命令失败,它就不会执行下一个命令。
第二种方法:
在ProgramToRun.py
文件中,将Documents/workspace/programfolder/src/
添加到PYTHONPATH,具体操作如下:
import sys
sys.path.append("/Users/username/Documents/workspace/programfolder/src/")
希望这对你有帮助。