Как я могу определить, выполняется ли сценарий Python из crontab? - PullRequest
5 голосов
/ 18 января 2010

Я хотел бы знать, как я могу определить, выполняется ли сценарий Python из crontab?

Мне не нужно решение, которое потребует добавления параметра, потому что я хочу иметь возможность обнаруживать это даже из импортированного модуля (не основного сценария).

Ответы [ 6 ]

19 голосов
/ 18 января 2010

Не совсем то, что вы спросили, но, возможно, вы хотите os.isatty(sys.stdout.fileno()), который сообщает, подключен ли stdout (грубо говоря) к терминалу. Будет ложным, если вы передадите вывод в файл или другой процесс или если процесс будет запущен из cron.

7 голосов
/ 18 января 2010

Проверьте его PPID - идентификатор его родительского процесса. Сравните это с cron pid; Если они одинаковы, он вызывается crontab.

Это может быть сделано:

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

PID процесса cron в этом примере - 6363. Стоит отметить, что PPID cron - 1 - процесс инициализации .

Теперь выясните, какой PID вашей программы на Python:

$  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.

EDIT:

Процесс cron может не вызывать ваш процесс напрямую. Следовательно, вам придется проходить PPID от вашего процесса вверх, пока не достигнете PPID = 1 или PPID = /usr/sbin/cron PID. Это легко сделать с помощью небольшой оболочки или скрипта Python; просто проанализируйте вывод ps:

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

Следующим шагом будет checkig / proc / 7238 и так далее. Опять же, это действительно легко реализовать с помощью сценария оболочки или Python.

Спасибо, @digitalarbeiter и @Noufal Ibrahim за то, что указали на это в своих комментариях.

5 голосов
/ 18 января 2010

Установить переменную среды при вызове команды cron. Это работает даже внутри модуля, так как вы можете просто проверить os.getenv().

1 голос
/ 18 января 2010

Более простой способ - передать флаг сценарию только из crontab, например --crontab, а затем просто проверить этот флаг.

0 голосов
/ 06 июня 2019

Ниже показано, как определить, есть ли в программе терминал и есть ли у него дисплей. В качестве задания 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" )

В качестве еще одного примера следующий код выбирает подходящий бэкэнд matplotlib при запуске из задания cron:

if os.getenv( "DISPLAY" ) is None:
    print( "Using Agg" )
    import matplotlib
    matplotlib.use('Agg')
0 голосов
/ 18 января 2010

Если вы хотите обнаружить это из импортированного модуля, я бы попросил основную программу установить глобальную переменную в модуле, которая будет выводить разные вещи в зависимости от значения этой глобальной переменной (и заставить основную программу решить, какустановите переменную через флаг, который вы будете использовать в вашем crontab).Это достаточно надежно (по сравнению с изучением PPID).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...