Python脚本没有在调用pysaunter的crontab中运行

der*_*ble 6 python shell cron crontab cron-task

我已经阅读了多篇帖子和许多文章,详细说明了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)
Run Code Online (Sandbox Code Playgroud)

步骤3的输出显示它正在找到egg并成功开始从pysaunter加载必要的模块,但是当它试图找到用于修改pysaunter的目录时它会中断.错误如下:

ImportError: no module named helpers
Run Code Online (Sandbox Code Playgroud)

我曾多次尝试将此路径添加到环境中,但它似乎永远不会找到包含helpers.py的目录.pysaunter -m foo -v从交互式shell调用时,该命令正常工作.

我在pysaunter上找不到多少帮助,所以我认为这里过多的pysaunter细节是不必要的.如果您了解更多有关pysaunter的信息,请告知我们您是否需要更多信息.我不知道该分享什么.

我还阅读了很多帖子,讨论了通过编辑.profile/.bash_profile来改变shell默认行为的能力.我试图找到一个可以使我的路径变量全局可访问的地方,但我找不到任何东西.我不确定这是怎么做的,它可以解决我的问题,所以如果你对此有所了解,请告诉我.

最后说明,这是在Mac 10.7.5上运行的.

der*_*ble 4

经过多次尝试和错误,以及很多很多 stackoverflow.com 文章和其他在线教程,并在 Perl 脚本的帮助下,我发现它做了类似的事情,我能够弄清楚需要做什么才能让它工作。

以下是确保一切设置正确的步骤:

  1. 确保您想要在其中测试脚本以确保其正常工作的任何 shell 的 .profile 或 .bash_profile 内的PYTHONPATH(可在此处此处找到,以及更多信息。请转到此处)中拥有所需的变量。

  2. 编辑您的 crontab 以包含在 cron 作业中运行脚本所需的目录(可在此处此处找到)。

    a) 确保将根目录包含在 PATH 变量 (.) 中,如此处所述。基本上,如果您使用命令运行可执行文件,它需要能够找到根目录或存储可执行文件的目录,也可能是这些:(/sbin:/bin:/usr/sbin:/usr/bin)。

  3. 在 crontab 文件中,创建一个 cronjob,它将当前目录更改为之前成功运行脚本的目录(例如,/Users/user/Documents/foo)。

    a) 如下所示:

    * * * * cd /Users/user/Documents/foo; bar -l doSomething -v 
    
    Run Code Online (Sandbox Code Playgroud)
  4. 由于我的问题专门涉及调用可执行文件,因此有必要注意,编写要运行的 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)
    
    Run Code Online (Sandbox Code Playgroud)

    第二个看起来像这样:

    ... #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)
    
    Run Code Online (Sandbox Code Playgroud)

    由于可执行文件需要调用它的 shell 中包含的 helpers 目录的路径,因此有必要将环境变量传递给可执行文件,如此处所述。但我发现,修改环境中的 PATH 变量对 cron 作业不起作用,但设置 PYTHONPATH 却可以。我在这里读到,shell 使用 PATH 变量仅查找可执行文件,因此对于 cronjob 内的新 shell,您需要向 shell 传递 PYTHONPATH 来查找新的 Python 模块。(Python 文档中也对此进行了解释。)

    问题中引用的子流程文档中解释了两种不同方法之间的差异,但可以在此处找到有关此模块的很好的教程。