Peut PHP détecter si son exécution à partir d'une tâche cron ou en ligne de commande?
Je suis à la recherche de façon à PHP pour détecter si un script a été exécuté à partir d'un manuel d'invocation sur un shell (en me connectant et en cours d'exécution), ou si il a été exécuté à partir de l'entrée crontab.
J'ai plusieurs type d'entretien de scripts écrits en php que j'ai mis à courir dans ma crontab. De temps en temps, j'ai besoin d'exécuter manuellement en avance sur le calendrier, ou si quelque chose de panne ou cassé, j'ai besoin d'exécuter une couple de fois.
Le problème c'est que j'ai aussi des notifications externes mis sur les tâches (poster sur twitter, l'envoi d'un e-mail, etc) que je NE veux pas arriver à chaque fois que je lance le script manuellement.
Je suis en php5 (si c'est important), c'est assez standard de linux de l'environnement du serveur.
Des idées?
- L'ajout d'une question liée: Détecter si un script PHP est exécuté de manière interactive ou pas
- Merci pour la référence!
Vous devez vous connecter pour publier un commentaire.
Au lieu de détecter lorsque le script est exécuté à partir de la crontab, il est probablement plus facile de détecter lorsque vous êtes en cours d'exécution à la main.
Il y a beaucoup de variables d'environnement (en $_ENV tableau) qui sont définies lorsque vous exécutez un script en ligne de commande. Ce sont de ces variera en fonction de votre serveur d'installation et de la façon dont vous vous connectez. Dans mon environnement, les variables d'environnement suivantes sont définies lors de l'exécution d'un script manuellement, qui ne sont pas présents lors de l'exécution de cron:
Il y a aussi les autres. Ainsi, par exemple, si vous utilisez SSH pour accéder à la boîte, puis la ligne suivante permettrait de détecter si le script est en cours d'exécution de cron:
$cron = !isset($_ENV['SSH_CLIENT']);
define( 'PHP_SAPI', ( php_sapi_name() == 'cli' ) ? ( isset( $_SERVER['TERM'] ) ? 1 : 2 ) : 0 );
php_sapi_name()
retournecgi-fcgi
lorsqu'il est exécuté par cron. En d'autres termes, si votre système est comme le mien, vous pouvez échanger la première ligne de cette réponse code avec:if (php_sapi_name() == 'cli' || php_sapi_name() == 'cgi-fcgi') {
.$_SERVER['term']
Vous pouvez configurer un paramètre supplémentaire, ou ajouter une ligne dans votre crontab, peut-être:
Et puis vous pouvez vérifier vos variables d'environnement pour le "CRON". Aussi, essayez de vérifier l' $variable SHELL, je ne suis pas sûr si/ce cron il met à la.
variables_order
doit inclure un " E " en php.ini pour que le$_ENV
tableau peupléesgetenv()
, sauf si vous êtes bloqué en mode sans échec.Voici ce que j'ai utiliser pour découvrir où le script est exécuté à partir de. Regardez les php_sapi_name fonction pour plus d'informations: http://www.php.net/manual/en/function.php-sapi-name.php
EDIT:
Si
php_sapi_name()
ne comprend pas cli (peut-être cli ou cli_server) on vérifie ensuite si$_SERVER['REMOTE_ADDR']
est vide. Lorsqu'il est appelé à partir de la ligne de commande, qui doit être vide.La bonne approche consiste à utiliser la posix_isatty fonction de() sur, par exemple, la sortie standard (stdout) descripteur de fichier, comme ceci:
PHP Warning: posix_isatty(): cannot seek on a pipe in /root/test.php on line 3
, j'ai donc utilisé le@
en face de l'appel au silence de l'avertissement. Aussi, veuillez noter que cette méthode permettra de détecter les appels dans la ligne de commande qui sont dirigés vers quelque chose d'autre que "pas un tty" - qui est essentiellement ce que je voulais, mais YMMV.Je pense que le plus universel solution est d'ajouter une variable d'environnement pour le cron de commande, et chercher sur le code. Il fonctionne sur tous les systèmes.
Si la commande exécutée par le cron est, par exemple:
Changer de
Alors vous pouvez le vérifier sur le code:
Je ne sais pas à propos de PHP en particulier, mais vous pouvez marcher jusqu'à l'arborescence des processus jusqu'à ce que vous avez trouvé soit init ou cron.
En supposant que PHP peut obtenir son propre ID de processus et d'exécuter des commandes externes, il devrait être une question de l'exécution de
ps -ef | grep pid
où pid est votre propre ID de processus et d'en extraire le parent de l'ID de processus (PPID) de celui-ci.Puis faire de même pour que PPID jusqu'à ce que vous atteindre le cron d'un parent ou d'init en tant que parent.
Par exemple, c'est mon arborescence des processus et vous pouvez voir la chaîne de propriété, 1 -> 6386 -> 6390 -> 6408.
Le même processus s'exécutent sous cron ressemblerait à:
Cette "marche de l'arborescence des processus" solution signifie que vous n'avez pas à vous inquiéter au sujet de l'introduction artificielle de paramètre pour indiquer si vous êtes en cours d'exécution en vertu de cron ou pas - vous pouvez oublier de le faire dans votre session interactive et les choses les choses.
Pas que je sache - probablement la solution la plus simple est de fournir un paramètre supplémentaire, vous-même dire le script de la façon dont elle a été invoquée.
Effrayant. Essayez
à la place. Client PHP Binaire ne pas l'envoyer. Terme de Type fonctionne, tout simplement lorsque PHP est utilisé en tant que module (ie apache) mais lors de l'exécution de php par le biais de l'interface CGI, utilisez l'exemple ci-dessus!
Je veux le regarder dans
$_ENV
(var_dump ()) et de vérifier si vous remarquez une différence lorsque vous l'exécutez vs lorsque la tâche cron exécute. Mis à part cela je ne pense pas qu'il y est un "officiel" de l'interrupteur qui vous dit ce qui s'est passé.Dans mon environnement, j'ai trouvé que
TERM
a été mis en$_SERVER
si vous exécutez à partir de la ligne de commande, mais pas de définir s'il est exécuté par Apache comme une requête web. J'ai mis en haut de mon script que je pourrais courir à partir de la ligne de commande, ou peut accéder via un navigateur web:Rembourrage pour les DONC de de 30 char min.
$_SERVER['SESSIONNAME']
contientConsole
si vous exécutez à partir de la CLI. Peut-être cela peut vous aider.Dans le cron de commande, ajouter
?source=cron
à la fin du chemin du script. Puis, dans votre script, vérifiez$_GET['source']
.EDIT: désolé, c'est un script shell ne peut donc pas utiliser qs. Vous pouvez, je pense, de passer des arguments dans la forme
php script.php arg1 arg2
puis de les lire avec$argv
.Une autre option serait de tester un environnement spécifique variable qui est définie lorsque le fichier php est appelé via le web et ne pas définir si géré par la ligne de commande.
Sur mon serveur web, je suis mise à l'essai si le APACHE_RUN_DIR variable d'environnement est définie comme ceci :
Pour s'assurer qu'il fonctionne sur votre serveur web, vous pouvez mettre un mannequin fichier php sur votre serveur web avec cette unique phrase :
1) le charger avec votre navigateur web et 2) le charger à partir de la ligne de commande comme ceci
Comparer les différences et les test de la variable appropriée.
posix_isatty(STDOUT) return FALSE
si la sortie de la cli appel est redirigé (tuyau ou un fichier)...Je pense qu'il serait préférable de lancer le cron de commande avec une option supplémentaire à la ligne de commande que vous n'auriez pas l'exécuter manuellement.
cron ferait:
manuel ferait:
Juste ajouter une option dans le script lui-même pour avoir le ext_updates param avoir une valeur par défaut false.
C'est très facile. Les Démons Cron toujours à l'exportation
MAILTO
variable d'environnement. Vérifier s'il existe et a une valeur non vide, alors vous l'exécution de cron.Sur mon Amazon Linux serveur, c'est ce qui a fonctionné pour moi:
$isCron = ( $_SERVER['HOME'] == '/' );
Le répertoire de base est défini à la vôtre, si vous venez de l'exécuter. Si vous utilisez sudo pour exécuter, le répertoire de base est défini dans /root.
Il est facile pour moi... Juste
count($_SERVER['argc'])
et si vous avez un résultat supérieur à zéro, il sera à cours d'un serveur. Vous avez juste besoin de les ajouter à votre$_SERVER['argv']
votre variable personnalisée, comme"CronJob"=true;