簡體   English   中英

如何確定是否從crontab執行python腳本?

[英]How can I determine if a python script is executed from crontab?

我想知道如何確定是否從crontab執行python腳本?

我不想要一個需要添加參數的解決方案,因為我希望能夠從導入的模塊(而不是主腳本)中檢測到這一點。

不是你問的,但也許你想要的是os.isatty(sys.stdout.fileno()) ,它告訴stdout是否連接到(粗略地說)一個終端。 如果將輸出通過管道傳輸到文件或其他進程,或者從cron運行進程,則為false。

檢查其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 - init進程

現在找出你的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在你的評論中指出它。

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')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM