我已阅读多篇帖子和许多文章,详细说明cron作业中的scipts需要保留在脚本本身内运行所必需的环境变量,因为在cron中打开了shell。我的情况是独特的,因为我的路径变量都是按照讨论的方式设置的,这反过来会使用subprocess.call()成功调用pysaunter python egg,但它似乎从那里分解。这导致整个过程在cron作业中中断。
为清楚起见,以下是我所指的步骤:
1) cronjob calls run_test.py -n foo
2) run_test.py sets the environment variables correctly
(cur_shell_path=sys.path (converted to proper path string, not shown here)
my_env= os.environ.copy()
my_env["PATH"] = my_env["PATH"] + cur_shell_path)
3) run_test.py calls subprocess.call("pysaunter -m foo -v", env=my_env, shell=True)
步骤3的输出显示它正在找到egg并成功开始从pysaunter加载必要的模块,但在尝试查找用于修改pysaunter的目录时它会中断。错误如下:
ImportError: no module named helpers
我尝试多次将此路径添加到环境中,但似乎找不到包含helpers.py的目录。从交互式shell调用时,pysaunter -m foo -v
命令正常工作。
我在pysaunter上找不到多少帮助,所以我认为这里过多的pysaunter细节是不必要的。如果您了解更多有关pysaunter的信息,请告知我们您是否需要更多信息。我不知道该分享什么。
我还阅读了很多帖子,讨论了通过编辑.profile / .bash_profile来改变shell默认行为的能力。我试图找到一个可以使我的路径变量全局可访问的地方,但我找不到任何东西。我不确定这是怎么做的,它可以解决我的问题,所以如果你对此有所了解,请告诉我。
最后说明,这是在Mac 10.7.5上运行。
答案 0 :(得分:3)
经过多次试验和错误,以及许多很多stackoverflow.com文章和其他在线教程,并在Perl脚本的帮助下,我发现做了类似的事情,我能够弄清楚需要做什么才能获得这个工作。
以下是确保正确设置所有内容的步骤:
确保您在PYTHONPATH中找到所需的变量(找到here和here,并获取更多信息。转到here).profile或.bash_profile对于您要测试脚本的任何shell,以确保它有效。
编辑您的crontab以包含运行您的目录所需的目录 cron作业中的脚本(找到here和here)。
a)确保将根目录包含在PATH变量(。)中,如here所述。基本上,如果您使用命令运行可执行文件,则需要能够找到root或存储可执行文件的目录,也可能是:(/ sbin:/ bin:/ usr / sbin:/ usr / bin)。
在您的crontab文件中,创建一个cronjob,它将当前目录更改为您之前成功运行该脚本的目录(例如,/ Users / user / Documents / foo)。
a)这将如下所示:
* * * * cd /Users/user/Documents/foo; bar -l doSomething -v
由于我的问题专门涉及调用可执行文件,因此有必要注意有多种方法可以编写Python脚本来运行(尽管在发现过程中我了解到这适用于任何使用的调用cron中的子进程)。
第一种方法如下:
... #some script calls
my_env = os.environ.copy()
my_env["PYTHONPATH"] = "{}:{}".format(os.environ["PATH"] ,"<path you want to include>")
os.chdir("<path/to/desired/directory>")
subprocess.Popen(<call_as_string>, env=my_env, shell=True)
第二个看起来像这样:
... #some script calls
os.environ["PYTHONPATH"] = "{}:{}".format(os.environ["PATH"] ,"<path you want to include>")
os.chdir("<path/to/desired/directory>")
subprocess.Popen(<call_as_list_of_arguments)
由于可执行文件需要从调用它的shell中包含的helpers目录的路径,因此有必要将环境变量传递给可执行文件,如here所述。但我发现,修改环境中的PATH变量对于cron作业不起作用,但是设置PYTHONPATH确实如此。我读here,shell使用PATH变量只查找可执行文件,因此对于cronjob中的新shell,你需要传递一个PYTHONPATH来查找新的Python模块。 (这也是explained in the Python docs。)
在问题中引用的子流程文档中解释了两种不同方法之间的差异,但可以找到关于此模块的一个很好的教程here。
答案 1 :(得分:1)
你所说的话毫无意义。
你说shell_env = sys.path
。 sys.path
是python查找模块的文件夹列表,而不是环境变量映射!
然后在subprocess.call
中使用它。也许你打算写env=my_env
。
这是下一个问题。首先,PATH
应该是由':'
分隔的文件夹列表。你只需将shell_path添加到最后一个文件夹中。
最后,python使用PYTHONPATH
作为列表来定位python模块(这似乎是你正在遇到的问题。)