如何确定是否从crontab执行python脚本?

时间:2010-01-18 15:17:07

标签: python unix terminal cron

我想知道如何确定是否从crontab执行python脚本?

我不想要一个需要添加参数的解决方案,因为我希望能够从导入的模块(而不是主脚本)中检测到这一点。

6 个答案:

答案 0 :(得分:19)

不完全是你提出的问题,但也许你想要的是os.isatty(sys.stdout.fileno()),它告诉stdout是否连接到(粗略地说)终端。如果将输出通过管道传输到文件或其他进程,或者进程是从cron运行,则为false。

答案 1 :(得分:7)

检查其PPID - 其父进程的ID。将其与cron pid进行比较;如果它们相同,则由crontab调用。

这可以通过以下方式完成:

$ sudo ps -Af | grep cron | grep -v grep
root  6363  1  0 10:17 ?  00:00:00 /usr/sbin/cron

此示例中的cron进程的PID为6363.值得一提的是,cron的PPID为1 - the init process

现在找出你的python程序的PID是什么:

$  sudo ps -Af | grep SorinSbarnea.py
adam  12992  6363  1 12:24 pts/2  00:04:21 /usr/bin/python SorinSbarnea.py

它的PID是12992,PPID是6363,所以它确实是由cron进程调用的。

修改

cron进程可能不会直接调用您的进程。因此,您必须向上遍历过程中的PPID,直到达到PPID = 1或PPID = /usr/sbin/cron的PID。这可以使用小shell或python脚本轻松完成;只解析ps

的输出
$ cat /proc/12992/status
....
Pid:    12992
PPid:   7238
Uid:    1000    1000    1000    1000
Gid:    1000    1000    1000    1000
...

下一步是checkig / proc / 7238,依此类推。同样,使用shell或python脚本很容易实现。

谢谢@digitalarbeiter和@Noufal Ibrahim在你的评论中指出它。

答案 2 :(得分:4)

cron命令调用中设置环境变量。这甚至可以在模块中使用,因为您只需检查os.getenv()

答案 3 :(得分:1)

更简单的解决方法是仅将标志从crontab传递给脚本,例如--crontab,然后只检查该标志。

答案 4 :(得分:0)

如果你想从导入的模块中检测到这个,我会让主程序在模块中设置一个全局变量,根据这个全局变量的值输出不同的东西(并让主程序决定如何通过您将在crontab中使用的标志设置变量。这非常强大(与学习PPID相比)。

答案 5 :(得分:0)

下面显示了如何检测程序是否具有终端以及是否具有显示器。作为cron作业,两者都将返回为None。

#!/usr/bin/python

import os

term = os.getenv( "TERM" )
print( "term %s"%term )

display = os.getenv( "DISPLAY" )
print( "display %s"%display )

从桌面终端会话运行时,输出将类似于以下内容:

term xterm-256color
display :0

当它作为cron作业运行时,输出将为:

term None
display None

您可以像这样测试其中任何一个的存在

if term is None:
    print( "no terminal" )

if display is None:
    print( "no display" )

再举一个例子,当从cron作业运行时,以下示例选择了适当的matplotlib后端:

if os.getenv( "DISPLAY" ) is None:
    print( "Using Agg" )
    import matplotlib
    matplotlib.use('Agg')