PHP는 cron 작업에서 실행되는지 명령줄에서 실행되는지 탐지할 수 있습니까?
나는 스크립트가 셸의 수동 호출(내가 로그인하여 실행)에서 실행되었는지 또는 crontab 항목에서 실행되었는지 여부를 탐지하기 위해 PHP로 가는 방법을 찾고 있습니다.
crontab에서 실행하도록 설정한 다양한 유지관리 유형 스크립트가 php로 작성되어 있습니다.때때로 예정보다 먼저 수동으로 실행해야 하거나 오류가 발생하거나 고장이 발생한 경우 몇 번 실행해야 합니다.
문제는 스크립트를 수동으로 실행할 때마다 수행하지 않으려는 작업(Twitter에 게시, 전자 메일 보내기 등)에도 외부 알림이 설정되어 있다는 것입니다.
저는 php5를 사용하고 있습니다(중요하다면), 그것은 상당히 표준적인 리눅스 서버 환경입니다.
아이디어 있어요?
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";
}
크론 탭에서 스크립트를 실행할 때 검색하는 대신 수동으로 실행할 때 검색하는 것이 더 쉬울 수 있습니다.
명령줄에서 스크립트를 실행할 때 설정되는 많은 환경 변수($_ENV 배열)가 있습니다.이러한 항목은 서버 설정 및 로그인 방법에 따라 달라집니다.내 환경에서는 cron에서 실행할 때 없는 스크립트를 수동으로 실행할 때 다음과 같은 환경 변수가 설정됩니다.
- 용어
- SSH_CLIENT
- SSH_TTY
- SSH_연결
다른 사람들도 있습니다.예를 들어 항상 SSH를 사용하여 상자에 액세스하는 경우 다음 행에서 스크립트가 cron에서 실행되고 있는지 여부를 감지합니다.
$cron = !isset($_ENV['SSH_CLIENT']);
추가 파라미터를 설정하거나 crontab에 다음과 같은 라인을 추가할 수 있습니다.
CRON=running
그런 다음 환경 변수에서 "CRON"을 확인할 수 있습니다. 또한 $SHELL 변수를 확인해 보십시오. cron이 설정하는 값이 무엇인지 잘 모르겠습니다.
다음은 스크립트가 실행되는 위치를 검색하는 데 사용하는 방법입니다.자세한 내용은 php_httpi_name 함수를 참조하십시오. 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";
}
편집: 만약php_sapi_name()
cli(cli 또는 cli_server일 수 있음)가 포함되어 있지 않은 경우$_SERVER['REMOTE_ADDR']
비어 있습니다.명령줄에서 호출할 때 이 값은 비어 있어야 합니다.
올바른 접근 방식은 다음과 같이 stdout 파일 설명자와 같은 posix_isatty() 함수를 사용하는 것입니다.
if (posix_isatty(STDOUT))
/* do interactive terminal stuff here */
가장 보편적인 해결책은 cron 명령어에 환경 변수를 추가하여 코드에서 찾는 것이라고 생각합니다.모든 시스템에서 작동합니다.
cron에 의해 실행되는 명령이 다음과 같은 경우:
"/usr/bin/php -q /var/www/vhosts/myuser/index.php"
로 변경
"CRON_MODE=1 /usr/bin/php -q /var/www/vhosts/myuser/index.php"
그런 다음 코드에서 확인할 수 있습니다.
if (!getenv('CRON_MODE'))
print "Sorry, only CRON can access this script";
구체적으로 PHP에 대해서는 모르겠지만 init 또는 cron을 찾을 때까지 프로세스 트리를 따라 올라갈 수 있습니다.
자체 명령을 할 수 하면 PHP를 실행하는 .ps -ef | grep pid
여기서 pid는 사용자 자신의 프로세스 ID이며 여기서 상위 프로세스 ID(PPID)를 추출합니다.
그런 다음 부모로서 cron에 도달하거나 부모로서 init에 도달할 때까지 해당 PPID에 동일한 작업을 수행합니다.
예를 들어, 이것은 제 프로세스 트리이고 소유권 체인을 볼 수 있습니다. 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
cron에서 실행되는 동일한 프로세스는 다음과 같습니다.
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
이 "프로세스 트리 위로 걷기" 솔루션은 cron에서 실행 중인지 여부를 나타내는 인위적인 매개 변수를 도입하는 것에 대해 걱정할 필요가 없다는 것을 의미합니다. 대화형 세션에서 수행하는 것을 잊어버리고 작업을 완료할 수도 있습니다.
소름끼치네요. 해보세요.
if (!isset($_SERVER['HTTP_USER_AGENT'])) {
대신.PHP Client Binary는 전송하지 않습니다.용어 유형은 PHP가 모듈(즉 아파치)로 사용될 때만 작동하지만 CGI 인터페이스를 통해 php를 실행할 때는 위의 예를 사용하십시오!
제가 알기로는 그렇지 않습니다. 아마도 가장 간단한 해결책은 스크립트에 어떻게 호출되었는지 알려주는 추가 매개 변수를 직접 제공하는 것입니다.
는 제가알습다니겠보아▁into에 대해 알아보겠습니다.$_ENV
할 때 (var_cronjob이 실행할 때의 차이를 확인합니다.)그 외에는 무슨 일이 일어났는지 알려주는 "공식적인" 스위치가 없다고 생각합니다.
내 환경에서, 나는 다음과 같은 것을 발견했습니다.TERM
에설된정에서 되었습니다.$_SERVER
명령행에서 실행되는 경우에는 웹 요청으로 Apache를 통해 실행되는 경우에는 설정되지 않습니다.명령줄에서 실행하거나 웹 브라우저를 통해 액세스할 수 있는 스크립트의 맨 위에 다음과 같이 입력합니다.
if (isset($_SERVER{'TERM'}))
{
class::doStuffShell();
}
else
{
class::doStuffWeb();
}
getenv('TERM')
SO의 30개의 매력을 위한 패딩.
에 cron 명서다추가다를 합니다.?source=cron
스크립트 경로의 끝으로 이동합니다.그런 다음 스크립트에서 확인합니다.$_GET['source']
.
편집: 죄송합니다. 셸 스크립트이므로 qs를 사용할 수 없습니다.제에, 제은생에, 그형로주전, 수태장을있의 으로 인수를 수 .php script.php arg1 arg2
그리고 나서 그것들을 읽습니다.$argv
.
다른 옵션은 php 파일이 웹을 통해 호출될 때 설정되고 명령줄에서 실행될 경우 설정되지 않는 특정 환경 변수를 테스트하는 것입니다.
웹 서버에서 Apache_RUN_DIR 환경 변수가 다음과 같이 설정되어 있는지 테스트 중입니다.
if (isset($_ENV["APACHE_RUN_DIR"])) {
// I'm called by a web user
}
else {
// I'm called by crontab
}
웹 서버에서 작동하도록 하려면 다음과 같은 단일 문을 사용하여 더미 php 파일을 웹 서버에 저장할 수 있습니다.
<?php var_dump($_ENV); ?>
그런 다음 1) 웹 브라우저로 로드하고 2) 명령행에서 로드합니다.
/usr/bin/php /var/www/yourpath/dummy.php
차이를 비교하고 적절한 변수를 검정합니다.
posix_isatty(STDOUT) return FALSE
CLI 호출의 출력이 리디렉션되는 경우(파이프 또는 파일)...
$_SERVER['SESSIONNAME']
포함하다Console
CLI에서 실행되는 경우도움이 될 수도 있습니다.
if(!$_SERVER['HTTP_HOST']) {
blabla();
}
수동으로 실행하지 않을 명령행에 추가 옵션과 함께 cron 명령어를 실행하는 것이 좋을 것 같습니다.
cron은 다음을 수행합니다.
command ext_updates=1
수동으로 하면 됩니다.
command
ext_updates 매개 변수의 기본값이 false가 되도록 스크립트 자체에 옵션을 추가하기만 하면 됩니다.
이것은 매우 쉽습니다.Cron Daemons 항상 내보내기MAILTO
환경 변수입니다.이 값이 존재하고 비어 있지 않은지 확인합니다. 그런 다음 cron에서 실행하고 있는지 확인합니다.
Amazon Linux 서버에서는 다음과 같은 이점이 있었습니다.
$isCron = ($_SERVER['HOME'] == '/' );
홈 디렉토리를 실행하기만 하면 홈 디렉토리가 사용자의 것으로 설정됩니다.sudo를 사용하여 실행할 경우 홈 디렉토리는 /root으로 설정됩니다.
(array) $argv
cron 작업이 실행될 때 설정됩니다.배열의 첫 번째 값은 cron 작업을 생성할 때 사용한 /path/to/file이 됩니다.의 다음 값$argv
/path/to/file 뒤에 오는 모든 매개 변수가 됩니다.
예를 들어, cron 작업 명령이 다음과 같이 표시됩니다.
php /path/to/file.php first second third
$argv의 값은 다음과 같습니다.["/path/to/file.php", "first", "second", "third"]
그러면 다음을 수행할 수 있습니다.
if (isset($argv) && is_array($argv) && in_array('first', $argv)) { /* do something */ }
저한테는 쉬운 일입니다.그저.count($_SERVER['argc'])
결과가 0보다 높으면 서버가 부족합니다.당신은 단지 당신의 것에 추가하기만 하면 됩니다.$_SERVER['argv']
사용자 정의 변수, 예를 들어"CronJob"=true;
언급URL : https://stackoverflow.com/questions/190759/can-php-detect-if-its-run-from-a-cron-job-or-from-the-command-line
'programing' 카테고리의 다른 글
FFMPEG 라이브러리를 사용하여 RTSP 스트림 수신 (0) | 2023.08.26 |
---|---|
어떻게 하면 1000개의 숫자로 구성된 두 집합을 서로 비교할 수 있습니까? (0) | 2023.08.21 |
python's sorted()는 어떤 알고리즘을 사용합니까? (0) | 2023.08.21 |
Kubernetes에 MariaDB ColumnStore를 설치하는 방법은 무엇입니까? (0) | 2023.08.21 |
"git add, git commit" 이전 또는 이후에 "git pull"을 수행해야 합니까? (0) | 2023.08.21 |