【问题标题】:Python subprocess with crontab带有 crontab 的 Python 子进程
【发布时间】:2020-05-12 08:20:16
【问题描述】:

我正在尝试使用 crontab 每分钟运行一次 test.py,它调用(在其他一些函数之后)带有参数的 test2.py。 当我在终端中运行“python3 test.py”时,我在任务管理器中看到了 test2.py。当我使用 crontab 时,情况并非如此。正如我在终端中看到的输出一样,Test.py 确实运行了。所有文件都在 /root/ 中。

Crontab:

PATH=/root
* * * * * /usr/bin/flock -n /tmp/5.lockfile /usr/bin/python3 /root/test.py > /dev/pts/3

Test.py:

import subprocess
import os
import time

print(os.environ['PATH']) #Gives \root

#Three different methods, doesn't work:
subprocess.call("python3 /root/test2.py 1", shell=True) 
subprocess.Popen("python3 test2.py 1", stdout=subprocess.PIPE, shell=True, preexec_fn=os.setsid)
os.system("test2.py 1")

time.sleep(30)

【问题讨论】:

  • 也许 python3 不在运行 crontab 的用户的路径中。无论如何,您可以考虑不使用 shell=True 和字符串命令行。使用sys.executable 查找当前解释器并进行参数listsubprocess.call([sys.executable,"/root/test2.py","1"])
  • 在 Crontab 中运行时路径通常不同。因此,我会尝试 subprocess.Popen("python3 /root/test2.py 1") 以确保在定位 test2.py 时没有混淆。
  • @Jean-FrançoisFabre 谢谢,这行得通。请将其发布为答案!

标签: python python-3.x cron subprocess


【解决方案1】:

可能是 python3 不在运行 crontab 的用户的路径中。所以你必须让你的脚本更加万无一失。

您可以考虑不使用shell=True 和字符串命令行:这是不好的做法并会导致问题(例如引用和安全问题)

无论系统路径是什么都可以使用 sys.executable 来查找当前解释器并创建一个参数 list 以避免将来出现问题,例如包含特殊字符的参数:

subprocess.call([sys.executable,"/root/test2.py","1"])

sys.executable 是当前运行脚本的解释器的完整路径,因此可以保证找到它。其余参数不依赖于用户(权限除外)

另外,也许检查subprocess.call的返回码,或者,如果调用必须成功,替换为subprocess.check_call

另一种方法是导入test2 并调用它的功能。这不会创建另一个进程,但这可能无关紧要,并且它具有优势(例如:允许返回 python 类型,不破坏异常链......)

【讨论】:

    猜你喜欢
    • 2015-04-16
    • 2010-11-25
    • 1970-01-01
    • 2017-07-27
    • 2018-11-27
    • 2015-01-03
    • 2019-12-01
    • 2021-06-02
    • 1970-01-01
    相关资源
    最近更新 更多