script manualmente job ejemplos ejecutar desde crear automaticamente php cron

manualmente - ¿Puede PHP detectar si se ejecuta desde un trabajo cron o desde la línea de comandos?



ejecutar crontab manualmente (20)

Creo que la solución más universal es agregar una variable de entorno al comando cron y buscarla en el código. Funcionará en todos los sistemas.

Si el comando ejecutado por el cron es, por ejemplo:

"/usr/bin/php -q /var/www/vhosts/myuser/index.php"

Cambiarlo a

"CRON_MODE=1 /usr/bin/php -q /var/www/vhosts/myuser/index.php"

Entonces puedes verificarlo en el código:

if (!getenv(''CRON_MODE'')) print "Sorry, only CRON can access this script";

Estoy buscando la manera de PHP para detectar si un script se ejecutó desde una invocación manual en un shell (yo ingresando y ejecutándolo), o si se ejecutó desde la entrada crontab.

Tengo varias secuencias de comandos de mantenimiento escritas en php que he configurado para ejecutar en mi crontab. Ocasionalmente, y debo ejecutarlos manualmente antes de lo previsto o si algo falla / se rompe, necesito ejecutarlos un par de veces.

El problema con esto es que también tengo algunas notificaciones externas establecidas en las tareas (publicar en Twitter, enviar un correo electrónico, etc.) que NO QUIERO que suceda cada vez que ejecuto el script manualmente.

Estoy usando php5 (si importa), es un entorno de servidor linux bastante estándar.

¿Algunas ideas?


Creo que sería mejor ejecutar el comando cron con una opción adicional en la línea de comando que no se ejecutaría manualmente.

cron haría:

command ext_updates=1

el manual haría:

command

Simplemente agregue una opción en el script para que ext_updates param tenga un valor predeterminado de falso.


El enfoque correcto es usar la función posix_isatty () en, por ejemplo, el descriptor de archivo stdout, así:

if (posix_isatty(STDOUT)) /* do interactive terminal stuff here */


En el comando cron, agregue ?source=cron al final de la ruta del script. Luego, en su secuencia de comandos, marque $_GET[''source''] .

EDIT: lo siento, es un script de shell por lo que no puede usar qs. Puede, creo, pasar argumentos en la forma php script.php arg1 arg2 y luego leerlos con $argv .


En lugar de detectar cuándo se ejecuta el script desde el crontab, probablemente sea más fácil detectarlo cuando lo ejecuta manualmente.

Hay muchas variables de entorno (en la matriz $ _ENV) que se establecen cuando ejecuta una secuencia de comandos desde la línea de comandos. Lo que estos varían dependerá de la configuración de su servidor y de cómo inicie sesión. En mi entorno, las siguientes variables de entorno se establecen cuando se ejecuta un script manualmente que no están presentes cuando se ejecuta desde cron:

  • TÉRMINO
  • SSH_CLIENT
  • SSH_TTY
  • SSH_CONNECTION

Hay otros también Por ejemplo, si siempre usa SSH para acceder al cuadro, la siguiente línea detectaría si el script se está ejecutando desde cron:

$cron = !isset($_ENV[''SSH_CLIENT'']);


En mi entorno, encontré que TERM se estableció en $_SERVER si se ejecuta desde la línea de comandos, pero no se establece si se ejecuta a través de Apache como una solicitud web. Puse esto en la parte superior de mi script que podría ejecutar desde la línea de comandos, o podría acceder a través de un navegador web:

if (isset($_SERVER{''TERM''})) { class::doStuffShell(); } else { class::doStuffWeb(); }


Es fácil para mí ... Solo count($_SERVER[''argc'']) y si tiene un resultado mayor que cero, se estará quedando sin servidor. Solo necesita agregar a su $_SERVER[''argv''] su variable personalizada, como "CronJob"=true;


Esto es lo que uso para descubrir de dónde se ejecuta el script. Mire la función php_sapi_name para más información: http://www.php.net/manual/en/function.php-sapi-name.php

$sapi_type = php_sapi_name(); if(substr($sapi_type, 0, 3) == ''cli'' || empty($_SERVER[''REMOTE_ADDR''])) { echo "shell"; } else { echo "webserver"; }

EDITAR: Si php_sapi_name() no incluye cli (podría ser cli o cli_server ), entonces verificamos si $_SERVER[''REMOTE_ADDR''] está vacío. Cuando se llama desde la línea de comando, esto debería estar vacío.


Esto es muy facil. Cron Daemons siempre exporta la variable de entorno MAILTO . Verifique si existe y tiene un valor no vacío; luego ejecuta desde cron.


Horripilante. Tratar

if (!isset($_SERVER[''HTTP_USER_AGENT''])) {

en lugar. PHP Client Binary no lo envía. El tipo de término simplemente funciona cuando PHP se utiliza como módulo (es decir, apache), pero cuando se ejecuta php a través de la interfaz CGI, utilice el ejemplo anterior.


Me gustaría ver $_ENV (var_dump ()) y comprobar si notas una diferencia cuando lo ejecutas frente a cuando el cronjob lo ejecuta. Aparte de eso, no creo que haya un cambio "oficial" que te diga lo que sucedió.


No es que yo sepa, probablemente la solución más simple es proporcionar un parámetro adicional para decirle al script cómo fue invocado.


No sé específicamente sobre PHP, pero puedes subir el árbol de procesos hasta que encuentres init o cron.

Suponiendo que PHP puede obtener su propio ID de proceso y ejecutar comandos externos, debería ser una cuestión de ejecutar ps -ef | grep pid ps -ef | grep pid donde pid es tu propio ID de proceso y extrae el ID de proceso padre (PPID) de él.

Luego haga lo mismo con ese PPID hasta que llegue a cron como padre o init como padre.

Por ejemplo, este es mi árbol de procesos y puede ver la cadena de propiedad, 1 -> 6386 -> 6390 -> 6408.

UID PID PPID C STIME TTY TIME CMD root 1 0 0 16:21 ? 00:00:00 /sbin/init allan 6386 1 0 19:04 ? 00:00:00 gnome-terminal --geom... allan 6390 6386 0 19:04 pts/0 00:00:00 bash allan 6408 6390 0 19:04 pts/0 00:00:00 ps -ef

Los mismos procesos que se ejecutan bajo cron se verían así:

UID PID PPID C STIME TTY TIME CMD root 1 0 0 16:21 ? 00:00:00 /sbin/init root 5704 1 0 16:22 ? 00:00:00 /usr/sbin/cron allan 6390 5704 0 19:04 pts/0 00:00:00 bash allan 6408 6390 0 19:04 pts/0 00:00:00 ps -ef

Esta solución de "caminar por el árbol de procesos" significa que no tiene que preocuparse por la introducción de un parámetro artificial para indicar si se está ejecutando bajo cron o no; puede olvidarse de hacerlo en su sesión interactiva y rellenar cosas.


Otra opción sería probar una variable de entorno específica que se establece cuando el archivo php se invoca a través de la web y no se establece si se ejecuta por la línea de comandos.

En mi servidor web, estoy probando si la variable de entorno APACHE_RUN_DIR está configurada así:

if (isset($_ENV["APACHE_RUN_DIR"])) { // I''m called by a web user } else { // I''m called by crontab }

Para asegurarse de que funcionará en su servidor web, puede poner un archivo php ficticio en su servidor web con esta única declaración:

<?php var_dump($_ENV); ?>

Luego 1) cárguelo con su navegador web y 2) cárguelo desde la línea de comandos de esta manera

/usr/bin/php /var/www/yourpath/dummy.php

Compara las diferencias y prueba la variable apropiada.


Puede configurar un parámetro adicional o agregar una línea en su crontab, quizás:

CRON=running

Y luego puede verificar las variables de entorno para "CRON". Además, intente comprobar la variable $ SHELL, no estoy seguro de si / qué cron lo establece.


$_SERVER[''SESSIONNAME''] contiene la Console si se ejecuta desde la CLI. Tal vez eso ayude.


posix_isatty(STDOUT) return FALSE si la salida de la llamada cli se redirige (tubería o archivo) ...


if (php_sapi_name() == ''cli'') { if (isset($_SERVER[''TERM''])) { echo "The script was run from a manual invocation on a shell"; } else { echo "The script was run from the crontab entry"; } } else { echo "The script was run from a webserver, or something else"; }


if(!$_SERVER[''HTTP_HOST'']) { blabla(); }


getenv(''TERM'')

Relleno para SO de 30 char min.