Eğer PHP bir cron işi veya komut satırından onun çalışma algılayabilir miyim?

18 Cevap php

Ben bir betik (beni giriş ve çalışan) bir kabuk üzerinde bir el çağırma çalıştırmak olup olmadığını tespit etmek PHP için yol arıyor, ya da crontab girişi çalıştırın eğer. Ediyorum

Ben benim crontab çalışacak şekilde ayarladığınız php yazılı çeşitli bakım türü komut dosyaları var. Bazen, ve ben elle planlanandan falan / kırık başarısız olursa, ben onları bir kaç kez çalıştırmak için gereken onları çalıştırmak gerekir.

Bu sorun ben de ben elle komut dosyasını çalıştırmak her şey olmasını istediğiniz DONT (vb, bir e-posta göndererek, twitter gönderme) görevleri içine yerleştirilen bazı dış bildirimleri olması.

(Eğer bu konularda) ben, onun oldukça standart bir linux sunucu ortamı php5 kullanıyorum.

Herhangi bir fikir?

18 Cevap

Bunun yerine komut crontab'ın çalıştırdığınızda tespit, bu elle çalışan olduğunuzda algılamak için muhtemelen daha kolay.

Ortam değişkenleri bir sürü komut satırından bir komut dosyasını çalıştırdığınızda ayarlanır ki ($ _ENV dizi) vardır. Bunlar ne sever kurulum bağlı olarak değişir ve sen benim ortamda oturum nasıl cron'nun çalıştığında mevcut değil elle bir komut dosyası çalıştırıldığında, aşağıdaki ortam değişkenleri ayarlanır:

  • DÖNEM
  • SSH_CLIENT
  • SSH_TTY
  • SSH_CONNECTION

Başkaları da vardır. Her zaman kutusuna erişmek için SSH kullanıyorsanız komut cron çalışan eğer Yani, örneğin, daha sonra aşağıdaki satırı tespit olacaktır:

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

Sen kurulum fazladan bir parametre olabilir, ya da belki de, crontab bir satır ekleyin:

CRON=running

Ve sonra "CRON" için ortam değişkenleri kontrol edebilirsiniz. Ayrıca, $ SHELL değişkeni kontrol deneyin, ne cron o ayarlar / emin değilim.

Burada komut yürütülür nerede olduğunu keşfetmek için kullanmak budur. Daha fazla bilgi için php_sapi_name işlevi bakmak: http://www.php.net/manual/en/function.php-sapi-name.php

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

Ben özellikle PHP bilmem ama init veya cron ya bulana kadar işlem ağacını kadar yürüyebiliyordu.

PHP kendi işlem kimliği almak ve dış komutları çalıştırabilirsiniz varsayarsak, bu ps -ef | grep pid pid kendi süreci kimliği nerede ve gelen ana süreç kimliği (PPID) ayıklamak yürütme meselesi olmalıdır o.

Bir ebeveyn olarak, bir ebeveyn ya da init gibi cron ulaşmak ya kadar Sonra o PPID için aynı şeyi.

Örneğin, bu benim süreç ağacı ve mülkiyet zinciri, 1 görebilirsiniz -> 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

Cron altında çalıştırmak aynı süreçler gibi görünecektir:

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

Bu çözüm "süreci ağaç kadar yürüyüş" Eğer cron'nun altında veya çalıştıran konum olmadığını göstermek için yapay bir parametreyi tanıtan hakkında endişelenmenize gerek yok demektir - Eğer interaktif oturumda ve malzeme şeyler kadar bunu unutabilir.

Doğru bir yaklaşım, örneğin üzerine posix_isatty () işlevini kullanmak için böylece gibi stdout dosya tanımlayıcı:

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

Değil, ben biliyorum - muhtemelen basit çözüm çağrılan nasıl komut söylemek için fazladan bir parametre kendiniz sağlamaktadır.

I $_ENV (var_dump () o) içine bakmak ve cronjob çalıştırır zaman vs çalıştırdığınızda bir fark olmadığını kontrol ediyorum. Bunun dışında ben ne söyler "resmi" bir anahtar olduğunu sanmıyorum.

Benim bir ortamda, ben TERM bir web isteği olarak Apache ile komut satırından çalıştırırsanız $_SERVER ayarlanır, ancak çalıştırırsanız ayarlanmış değildi bulundu. Ben bir web tarayıcısı üzerinden erişmek olabilir Ben komut satırından çalıştırmak, ya da belki benim yazısının üstündeki bu koymak:

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

Ben en evrensel çözüm cron komutu bir ortam değişkeni eklemek ve kod bunun için bakmak olduğunu düşünüyorum. Her sistem üzerinde çalışacak.

Cron tarafından yürütülen komut örneğin ise:

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

Bunu değiştirin

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

Sonra kodu kontrol edebilirsiniz:

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

Ürpertici. Denemek

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

yerine. PHP Müşteri İkili göndermek yok. Dönem Türü PHP modülü (yani apache) olarak kullanıldığında sadece çalışır ama CGI arayüzü üzerinden php çalıştırırken, yukarıdaki örnek kullanmak!

Cron komutu, komut yolun sonuna ?source=cron ekleyin. Sonra, komut, kontrol $_GET['source'].

EDIT: Üzgünüm, o kadar qs kullanamazsınız bir betiğimiz bulunuyor. Sen, ben düşünüyorum, şeklinde argümanları geçmek php script.php arg1 arg2 ve $argv ile okuyabilirsiniz.

getenv('TERM')

Yani 30 karakter dakika Dolgu.

CLI'den çalıştırırsanız $_SERVER['SESSIONNAME'] Console içerir. Belki bu yardımcı olur.

Başka bir seçenek php dosyası web üzerinden çağrıldığında set değil komut koşucu eğer ayarlanmış bir özel bir ortam değişkeni test etmek olacaktır.

APACHE_RUN_DIR ortam değişkeni böyle ayarlandığında eğer benim web sunucusu ben test ediyorum:

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

O web sunucusu üzerinde çalışacağından emin olmak için, bu tek deyimi ile web sunucusu üzerinde bir kukla php dosyası koyabilirsiniz:

<?php var_dump($_ENV);  ?>

Sonra 1) web tarayıcısı ile yük ve 2) bu gibi komut ile yükleyin

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

Farklılıkları karşılaştırmak ve uygun değişken sınamak.

posix_isatty(STDOUT) return FALSE cli aramanın çıkış yönlendirilir ise (boru veya dosya) ...

Ben elle çalıştırmak olmaz komut satırında bir ek seçeneği ile cron Commmand çalıştırmak için daha iyi olacağını düşünüyorum.

cron yapardı:

command ext_updates=1

manuel yapardı:

command 

Sadece yanlış bir varsayılan değere sahip ext_updates param var komut kendisi bir seçenek ekleyin.

Bu çok kolaydır. Cron Cinleri her zaman ihracat MAILTO çevre değişkeni. Bir boş olmayan bir değer varsa ve varsa kontrol edin - o zaman cron'nun çalışan.

Bu benim için ... Sadece count($_SERVER['argc']) kolay ve sıfırdan bir sonuç daha var eğer bir sunucu üzerinden yayınlanmaya başlayacak. Sadece "CronJob"=true; gibi, $_SERVER['argv'] özel değişkene eklemek gerekir