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

如何确定是否从crontab执行python脚本?,python,unix,terminal,cron,Python,Unix,Terminal,Cron,我想知道如何确定是否从crontab执行python脚本 我不想要需要添加参数的解决方案,因为我希望能够从导入的模块(而不是主脚本)中检测到这一点。检查其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。值

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


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

检查其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-

现在了解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
...
下一步是检查ig/proc/7238,依此类推。同样,使用shell或python脚本很容易实现


谢谢,@digitalarbeiter和@Noufal Ibrahim在您的评论中指出了这一点。

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

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

一个更简单的解决方法是只从crontab向脚本传递一个标志,如--crontab,然后只检查该标志。

如果您想从导入的模块中检测到这一点,我会让主程序在模块中设置一个全局变量,这将根据这个全局变量的值输出不同的内容(并且让主程序决定如何通过crontab中使用的标志来设置变量)。这是非常稳健的(与研究PPID相比)。

下面展示了如何检测程序是否有终端以及是否有显示器。作为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')

你为什么想知道这个?例如,我想改变它输出的方式。当从终端运行时,我想通过ANSI转义序列使用颜色,但当从终端运行时,我想要纯文本以接收漂亮的电子邮件。然后检查终端,而不是cron。@digitalarbeiter:我想这只是一个例子。也许他想要比这更复杂一点的东西。@Stefano:是的,但是“显式比隐式好”。明确地检查您实际需要什么。用于术语,用于行为中的任何其他更改。cron将在一个新的shell中运行crontab条目,该shell将是Python脚本的PPID。您需要比较PPID的PPID。这假设父级(cron)直接从子级派生而来,其间没有外壳或其他东西。并非总是正确的。+1如果您希望根据是否向“屏幕”输出不同的输出,那么这样做是正确的。
sys.stdout.isatty()
os.isatty(sys.stdout.fileno())
。是的,但他不想这样做。原始帖子明确指出,这不是他想要的。