[英]How can I determine if a python script is executed from crontab?
I would like to know how can I determine if a python script is executed from crontab? 我想知道如何确定是否从crontab执行python脚本?
I don't want a solution that will require adding a parameter because I want to be able to detect this even from an imported module (not the main script). 我不想要一个需要添加参数的解决方案,因为我希望能够从导入的模块(而不是主脚本)中检测到这一点。
Not quite what you asked, but maybe what you want is os.isatty(sys.stdout.fileno())
, which tells if stdout
is connected to (roughly speaking) a terminal. 不是你问的,但也许你想要的是
os.isatty(sys.stdout.fileno())
,它告诉stdout
是否连接到(粗略地说)一个终端。 It will be false if you pipe the output to a file or another process, or if the process is run from cron. 如果将输出通过管道传输到文件或其他进程,或者从cron运行进程,则为false。
Check its PPID - the ID of its parent process. 检查其PPID - 其父进程的ID。 Compare that to the cron pid;
将其与cron pid进行比较; If they are the same, it was invoked by the crontab.
如果它们相同,则由crontab调用。
This can be done by: 这可以通过以下方式完成:
$ sudo ps -Af | grep cron | grep -v grep
root 6363 1 0 10:17 ? 00:00:00 /usr/sbin/cron
The PID of the cron process in this example is 6363. It is worth mentioning that the PPID of cron is 1 - the init process . 此示例中的cron进程的PID为6363.值得一提的是,cron的PPID为1 - init进程 。
Now find out what is the PID of your python program: 现在找出你的python程序的PID是什么:
$ sudo ps -Af | grep SorinSbarnea.py
adam 12992 6363 1 12:24 pts/2 00:04:21 /usr/bin/python SorinSbarnea.py
Its PID is 12992 and PPID is 6363, so it was indeed invoked by the cron process. 它的PID是12992,PPID是6363,所以它确实是由cron进程调用的。
EDIT: 编辑:
The cron process might not invoke your process directly. cron进程可能不会直接调用您的进程。 Hence, you'll have to traverse the PPIDs from your process upwards, till reaching PPID=1 or PPID=
/usr/sbin/cron
's PID. 因此,您必须向上遍历过程中的PPID,直到达到PPID = 1或PPID =
/usr/sbin/cron
的PID。 This can easily be done using a small shell or python script; 这可以使用小shell或python脚本轻松完成; just parse the output of
ps
: 只解析
ps
的输出:
$ cat /proc/12992/status
....
Pid: 12992
PPid: 7238
Uid: 1000 1000 1000 1000
Gid: 1000 1000 1000 1000
...
The next step would be checkig /proc/7238, and so forth. 下一步是checkig / proc / 7238,依此类推。 Again, This is really easy to implement using shell or python script.
同样,使用shell或python脚本实现这很容易。
Thanks, @digitalarbeiter and @Noufal Ibrahim for pointing it out in your comments. 谢谢@digitalarbeiter和@Noufal Ibrahim在你的评论中指出它。
Set an environment variable at the cron
command invocation. 在
cron
命令调用中设置环境变量。 That works even within a module, as you can just check os.getenv()
. 这甚至可以在一个模块中工作,因为你可以检查
os.getenv()
。
一个更简单的解决方法是仅将标志从crontab传递给脚本,如--crontab,然后只检查该标志。
If you want to detect this from an imported module, I would have the main program set a global variable in the module, which would output different things depending on the value of this global variable (and have the main program decide how to set the variable through a flag that you would use in your crontab). 如果你想从导入的模块中检测到这个,我会让主程序在模块中设置一个全局变量,根据这个全局变量的值输出不同的东西(并让主程序决定如何设置变量通过你将在你的crontab中使用的标志)。 This is quite robust (comparing to studying PPIDs).
这非常强大(与研究PPID相比)。
The following shows how to detect whether the program has a terminal and whether it has a display. 以下显示如何检测程序是否具有终端以及是否具有显示。 As a cron job, both will be returned as None.
作为一个cron作业,两者都将作为None返回。
#!/usr/bin/python
import os
term = os.getenv( "TERM" )
print( "term %s"%term )
display = os.getenv( "DISPLAY" )
print( "display %s"%display )
The output when run from a desktop terminal session will be similar to the following: 从桌面终端会话运行时的输出将类似于以下内容:
term xterm-256color
display :0
And when it is run as a cron job, the output will be: 当它作为cron作业运行时,输出将是:
term None
display None
You can test for the presence of either of these, like this 您可以测试其中任何一个的存在,如下所示
if term is None:
print( "no terminal" )
if display is None:
print( "no display" )
For one further example, the following selects an appropriate matplotlib backend when run from a cron job: 再举一个例子,当从cron作业运行时,以下选择适当的matplotlib后端:
if os.getenv( "DISPLAY" ) is None:
print( "Using Agg" )
import matplotlib
matplotlib.use('Agg')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.