2010-01-18 14 views
5

Mi piacerebbe sapere come posso determinare se uno script python viene eseguito da crontab?Come posso determinare se uno script python viene eseguito da crontab?

Non voglio una soluzione che richiederà l'aggiunta di un parametro perché voglio essere in grado di rilevare questo anche da un modulo importato (non lo script principale).

+2

perché vorresti saperlo? – SilentGhost

+1

Ad esempio, voglio cambiare il modo in cui produce l'output. Quando si esegue dal terminale voglio usare la colorazione tramite sequenze di escape ANSI, ma durante l'esecuzione dal terminal voglio testo normale al fine di ricevere messaggi di posta elettronica belle. – sorin

+3

Quindi controlla il terminale, non per cron. – digitalarbeiter

risposta

19

Non proprio quello che hai chiesto, ma forse quello che vuoi è os.isatty(sys.stdout.fileno()), che indica se stdout è collegato a (approssimativamente) un terminale. Sarà falso se si canalizza l'output in un file o in un altro processo o se il processo viene eseguito da cron.

+1

+1 Questa sarebbe la cosa giusta da fare se si desidera un output diverso a seconda che si stia trasmettendo allo 'schermo' o meno. –

+3

** 'sys.stdout.isatty()' ** è più semplice di 'os.isatty (sys.stdout.fileno())'. –

7

Controllare il suo PPID: l'ID del processo padre. Confrontalo con il cron pid; Se sono uguali, è stato invocato dal crontab.

Questo può essere fatto:

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

Il PID del processo cron in questo esempio è 6363. Vale la pena ricordare che l'PPID di cron è 1 - the init process.

Ora scoprire che cosa è il PID del programma Python:

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

suo PID è 12992 e PPID è 6363, quindi è stato infatti invocato dal processo cron.

EDIT:

Il processo di cron non potrebbe invocare direttamente il processo. Quindi, dovrai attraversare i PPID dal processo verso l'alto, fino a raggiungere il PID di PPID = 1 o PPID = /usr/sbin/cron. Questo può essere fatto facilmente usando una piccola shell o uno script python; basta analizzare l'output di ps:

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

Il passo successivo sarebbe checkig/proc/7238, e così via. Ancora una volta, questo è veramente facile da implementare usando shell o script python.

Grazie, @digitalarbeiter e @Noufal Ibrahim per averlo indicato nei commenti.

+3

cron eseguirà la tua voce crontab in una nuova shell, che sarebbe il PPID del tuo script Python. Avrai bisogno di confrontare il PPID del PPID. – digitalarbeiter

+2

Questo presuppone che il genitore (cron) sia stato generato direttamente dal bambino senza una shell o qualcos'altro in mezzo. Non sempre vero –

4

Impostare una variabile di ambiente al richiamo del comando cron. Funziona anche all'interno di un modulo, come puoi semplicemente controllare os.getenv().

2

Una soluzione più semplice sarebbe quella di passare una bandiera allo script solo dal crontab, come --crontab, e poi basta verificare la presenza di quella bandiera.

+2

ma lui non vuole farlo. –

0

Se si vuole rilevare questo da un modulo importato, avrei il programma principale impostare una variabile globale nel modulo, che sarebbe uscita cose diverse a seconda del valore di questa variabile globale (e avere il programma principale decidere come per impostare la variabile attraverso un flag che useresti nel tuo crontab). Questo è abbastanza robusto (rispetto allo studio dei PPID).

Problemi correlati