PHP를 쉘에서 실행 시킬때(CLI 환경) restart 시키는 방법 > PHP
PHP

PHP를 쉘에서 실행 시킬때(CLI 환경) restart 시키는 방법

조회 993회 댓글 0건

PHP를 웹서버를 통해서 실행 시키는 것을 흔히 사용하지만

쉘에서 실행 시키는 경우도 있습니다. 통상 CLI 환경이라고 합니다.


아래는 웹브라우저에 출력을 내보는것이 아니라 쉘에서 실행 시키는 경우 스케줄에 등록하여 매일 재시작 해야 되는 경우 필요한것입니다.

현재 실행 중인 프로그램을 강제 종료하고 스케줄에 의해 다시 실행시크는 형태의 프로그램을 만들어야 할 경우 유용 합니다.


  /**
   *
   * Linux 쉘에서 백그라운드 실행 시킬때 PID 관리를 위한것
   *
   */
  class PhpRestart
  {
    private $HOST_NAME  = '';
    private $TYPE       = 'restart';
    private $STATUS     = '';
    private $_PID_      = 0;
    private $FILE_PID   = '';

    function __construct( string $TYPE='' )
    {
      if ( strlen($TYPE) < 1 ) $TYPE = 'start';
      $this->_PID_      = getmypid();
      $this->TYPE       = $TYPE;
      $this->HOST_NAME  = php_uname('n');
      $this->FILE_PID   =  __DIR__ . '/testphp_' . $this->_PID_ . '.pid';

      if ( $TYPE == 'start' ) {
        $this->start();
      }
      else if ( $TYPE == 'stop' ) {
        $this->stop();
      }
      else if ( $TYPE == 'restart' ) {
        $this->restart();
      }
    }

    /**
     * 파일이 있으면 kill 처리 후 pid 파일을 생성 한다.
     *
     * @return [type]
     *
     */
    private function start() {
      if ( is_file($this->FILE_PID) ) $this->kill();

      $wrtSize  = file_put_contents($this->FILE_PID, $this->_PID_);
      echo date('Y-m-d H:i:s ') . "PID 생성: $this->_PID_" . ' / pidFile: ' . $this->FILE_PID . PHP_EOL;
      return $wrtSize;
    }

    private function restart() {
      $rUnlink  = $this->kill();
      $wrtSize  = $this->start();

      echo date('Y-m-d H:i:s ') . "STATUS: $this->STATUS -> $this->_PID_ / $wrtSize:$this->FILE_PID / HOST_NAME:$this->HOST_NAME \n";

      return $wrtSize;
    }

    private function stop() {
      $rUnlink  = $this->kill();

      echo date('Y-m-d H:i:s ') . "unlink: $rUnlink / 프로그램을 종료 합니다. \n";
      exit;
    }

    private function kill()
    {
      if ( is_file($this->FILE_PID) )
      {
        $pid_no   = file_get_contents($this->FILE_PID);
        $rExec    = shell_exec("/bin/kill $pid_no");
        $rUnlink  = unlink($this->FILE_PID);

        echo date('Y-m-d H:i:s ') . "STATUS: $this->STATUS -> $rExec / $rUnlink: $this->FILE_PID \n";
        return $rUnlink;
      }
      else {
        echo date('Y-m-d H:i:s ') . "$this->FILE_PID 파일이 없습니다. " . PHP_EOL;
        return false;
      }
    }

    public function get_pid() {
      return $this->_PID_;
    }

    public function get_status() {
      return $this->STATUS;
    }

    public function get_pidfile() {
      return $this->FILE_PID;
    }
  }

  $oPhpExec   = new PhpRestart( 'restart' );
  echo date('Y-m-d H:i:s ') . '생성된 pid 값은: ' . $oPhpExec->get_pid() . '입니다.' . PHP_EOL;
 


* 클래스가 복잡해 보인다면 간단한 아래를 참고

  - 쉘에서 실행할때 프로세스(pid) 저장후 재시작(restart) 할때 kill(종료) 시키기 > PHP 


* 클래스 만들때 :: 두개 찍어서 직접 메소드 호출하고 자 할때는 아래를 참고하세요.

  중요한것은 퍼블릭 이어야 합니다.

  - 모던php 사용시 흔하게 볼 수 있는 한가지 static > PHP 



  class Parent2 {
    function getNew() : string {
      return 'parent - getNew print: ' . __METHOD__ . PHP_EOL;
    }
  }
  class Child extends Parent2
  {
    static $ymd2 = ''; //

    public static function setYmd( string $ymd='' ) {
      if (strtotime($ymd) < 1) {
        $ymd      = date('Y-m-d H:i:s');
      }
      self::$ymd2    = $ymd;
    }

    public function getYmd() {
      return self::$ymd2;
    }

    public function get_parent_new() {
      return parent::getNew();
    }
  }

  echo date('Y-m-d H:i:s ') . '설정:  ' . Child::setYmd( 'testYmd' ) . PHP_EOL;
  echo date('Y-m-d H:i:s ') . '출력1: ' . Child::getYmd() . PHP_EOL;
  echo date('Y-m-d H:i:s ') . '출력2: ' . Child::get_parent_new() . PHP_EOL;
 


범위확인 연산자에 - 더블콜론에 대해선 메뉴얼을 보시는것이 좋습니다.

PHP : 스코프 해석 연산자 (::) - 수동


아래는 맨위에 있는것을 더블콜론으로 만들어 보았습니다. static가 아니면 접근이 되도 VSCODE에선 파란색줄이 보입니다.

접근과 별도의 객체 생성이 아닌 직접접근을 하려면 어딘가에 있어야 하니 가져올 수 있는 권한이 있어야 한 다는것을 생각하면 됩니다.


  /**
   *
   * Linux 쉘에서 백그라운드 실행 시킬때 PID 관리를 위한것
   *
   */
  class PhpRestart
  {
    static $HOST_NAME  = '';
    static $TYPE       = 'restart';
    static $_PID_      = 0;
    static $FILE_PID   = '';

    public static function set_config( string $TYPE='' )
    {
      if ( strlen($TYPE) < 1 ) $TYPE = 'start';
      self::$_PID_      = getmypid();
      self::$TYPE       = $TYPE;
      self::$HOST_NAME  = php_uname('n');
      self::$FILE_PID   =  __DIR__ . '/testphp_' . self::$_PID_ . '.pid';
    }

    /**
     * 파일이 있으면 kill 처리 후 pid 파일을 생성 한다.
     *
     * @return [type]
     *
     */
    static function start() {
      if ( is_file(self::$FILE_PID) ) self::kill();

      $wrtSize  = file_put_contents(self::$FILE_PID, self::$_PID_);
      echo date('Y-m-d H:i:s ') . self::$TYPE . " PID 생성: " . self::$_PID_ .  ' / pidFile: ' . self::$FILE_PID . PHP_EOL;
      return $wrtSize;
    }

    static function restart() {
      $rUnlink  = self::kill();
      $wrtSize  = self::start();

      echo date('Y-m-d H:i:s ') . self::$TYPE . " PID: " . self::$_PID_ . " / $wrtSize:" . self::$FILE_PID . " / HOST_NAME:" . self::$HOST_NAME . PHP_EOL;;

      return $wrtSize;
    }

    static function stop() {
      $rUnlink  = self::kill();

      echo date('Y-m-d H:i:s ') . self::$TYPE .  " unlink: $rUnlink / 프로그램을 종료 합니다. \n";
      exit;
    }

    static function kill()
    {
      if ( is_file(self::$FILE_PID) )
      {
        $pid_no   = file_get_contents(self::$FILE_PID);
        $rExec    = shell_exec("/bin/kill $pid_no");
        $rUnlink  = unlink(self::$FILE_PID);

        echo date('Y-m-d H:i:s ') . self::$TYPE . " rExec: $rExec / $rUnlink: " . self::$FILE_PID . PHP_EOL;
        return $rUnlink;
      }
      else {
        echo date('Y-m-d H:i:s ') . self::$TYPE . " FILE_PID: " . self::$FILE_PID . " 파일이 없습니다. " . PHP_EOL;
        return false;
      }
    }

    public function get_pid() {
      return self::$_PID_;
    }

    public function get_pidfile() {
      return self::$FILE_PID;
    }
  }

  // 실행방법 1
  PhpRestart::set_config('start');
  PhpRestart::start();
  echo date('Y-m-d H:i:s ') . PhpRestart::$TYPE . ' 생성된 pid 값은: ' . PhpRestart::get_pid() . '입니다.' . PHP_EOL;

  // 실행방법 2
  $oPhpExec   = new PhpRestart();
  $oPhpExec->set_config('start');
  $oPhpExec->start();
  echo date('Y-m-d H:i:s ') . $oPhpExec->TYPE . ' 생성된 pid 값은: ' . $oPhpExec->get_pid() . '입니다.' . PHP_EOL;
 


* 참고할것

  - 쉘에서 실행할때 프로세스(pid) 저장후 재시작(restart) 할때 kill(종료) 시키기 > PHP 



  • 페이스북으로 공유
  • 트위터로  공유
  • 구글플러스로 공유
전체 201건 1 페이지
  • profile_image 아파치 로그에서 특정페이지(URL) 호출의 횟수를 알아봐야 하는 경우 아래 프로그램을 자신의 환경에 맞게 수정하여 사용하면 됩니다.그리고 저 같은 경우 로그의 갯수가 몇만개 밖에 안되서 문제 되지 않지만 더 많을 경우 1차 2차 필터링 과정을 거치는 방식을 사용해서 처리 해야 하는것 참고하 주세요.기본 방식이 중요하기 때문에 아래를 응용해서 사용하면 됩니다.  $urlCounts = [];  while ($line = fgets(STDIN)) {      if (preg_match('/^.*"GET ([^"]+) HTTP/', $line, $matches)) {          $url = urldecode($match…
  • profile_image 프로그램이 멈추는 경우도 있기 때문에 이런 경우는try {} catch {} 로 잡아서 멈추지 않게 처리 해야 합니다.● 오류 로그와 관련하야 PHP 8 에서 중요한 부분은 아래와 같습니다.- 에러 출력을 위한 설정 - 반드시 로그를 남기는 것이 있어야 화면에 출력이 되질 않는다.- 그리고 예외처리 해서 잡은 것은 당연하게 echo 찍은 것이면 화면에 출력이 된다. 그렇기 때문에 웹사이트 제작시에는 적합하지 않기 때문에 함수 안에서 오류를 돌려 주고 필요한 경우만 출력하게 해야 합니다.     # error 출력을 위한 설정 - 반드시 로그를 남기는 것이 있어야 화면에 출력이 되질 않는다.    ini_set('disp…
  • profile_image 두가지 방식을 사용 할 수 있는데요. 가능하면 약간 복잡스러워도 새로 나온것을 사용하세요.● finfo Fileinfo 확장의 여러 기능을 사용할 수 있도록 하며 특히 FILEINFO_MIME_TYPE 외에도 FILEINFO_MIME 등의 옵션을 사용하여 더 많은 정보를 제공할 수 있습니다. 따라서 더 유연하고 강력한 기능을 제공합니다.● mime_content_type  이 함수는 단순히 파일의 MIME 타입을 반환하는데 사용됩니다. 이 함수는 매우 간단하며 추가적인 설정 옵션이 없습니다.    # 1) finfo     function getFileType($filePath) {        $finfo = finf…
  • profile_image PHP만 그런것은 아니지만 지원하는 기간이 너무 짧습니다.세월은 생각보다 너무 짜르게 흘러가서 업그레이드 하다가 시간 다 보내겠어요~ 오늘자 기준으로 PHP 지원되는 버전을 확인해 봤는데 이렇네요~대부분 PHP 7 많이 사용하고 있을텐데 보안 업그레이드도 종료 된지 한참 입니다.사용자가 기능 업그레이드 보다 보안 업그레이드 기간 길게 가져가 달라고 하는게 맞을 텐데...
  • profile_image 서비스용이 아니라 쉘에서 실행하는 용도로 설치 하기 위한것으로 별도의 환경설정 필요 없이 이정도만 해주면 당장 쉘에서 사용하는데는 지장이 없다.▷ 난 이렇게 버전별로 심볼릭 링크를 걸어서 사용 한다./usr/localln -s /opt/remi/php83/root/usr/ php83▷ 이전 버전에서 목록을 보고 당장 필요한것만 골라 보았다.목록을 확인하는 방법은 yum search php83 명령을 통해서 가능하다. opcachecurlbcmathctypedomexiffileinfogdiconvjsonmbstringsimplexmlsnmpsocketsxmlxmlwritermcryptmysqlibrotlicrypto▷ 위…
  • profile_image 언어도 용도에 따라 적합한쪽의 것을 사용하는것 처럼 함수와 클래스 어느것이 위에 있고 아래에 있는것은 아닙니다. 용도에 따라 훨씬 좋은 방식으로 사용 할 수 있는 것이죠 예를 들면 시장에서 닭을 자를 때 쓰는칼과 요리할때 야채를 써는 칼은 서로 용도가 다른것 처럼 말입니다. * 함수1-1) 함수 장점- 간단함: 함수를 정의하고 불러오는 방식이 매우 직관적입니다.- 초기 학습 곡선이 낮음: 객체 지향 프로그래밍(OOP)에 대한 이해가 필요 없습니다.- 가벼움: 클래스의 오버헤드 없이 필요한 함수만 불러올 수 있습니다.1-2) 함수 단점- 네임스페이스 충돌: 여러 파일에서 동일한 이름의 함수가 있을 경우 충돌이 발생할 수 …
  • profile_image 제가 만든것은 아니고 테스트 한것을 정리하여 올린 것입니다. 음력 -> 양력으로 변경하는 라이브러리 흔하고 간단할줄 알았는데 생각외로 복잡하고 제대로 되는것을 찾기도 쉽지 않았습니다.여기선 PHP 8.1에서 테스트 한것입니다. PHP8 부터는 isset 같은것을 사용해야 되는 부분만 참고하면 되고 깃허브에 있는 예제가 모두 실행 되는것은 아니었습니다. 제가 필요한 음력, 양력으로 변경하는 부분이 문제가 없었습니다.만세력의 문제점등 라이센스 관련하여 저에겐 없고 깃허브에 보면 자세히 설명이 되어 있습니다.https://github.com/OOPS-ORG-PHP/Lunar 1) pear 설치하기 위한 파일을 받는다.w…
  • profile_image 앞으로 @ 사용하지 말라고 하니 새로 만드는 프로그램은 try-catch 감싸서 처리 하는 것이 좋다.그래서 필요한 것으로 아래를 참고하면 된다. 그리고 아래 복원하는 함수면 한 줄이기 때문에 함수가 왜? 필요할까 싶지만 이런 경우도 함수로 만들어 사용하면 후에 어려운 일이 발생 했을 때 해결 할 수 있는 좋은 일이 생기게 되기도 한다.  # 사용자 오류처리기   convertErrorsToExceptions();   #   try {    $link = "https://www.test2341.com";    $html = file_get_contents($link, false, null);  } catch (Error…
  • profile_image 내장함수에 strip_tags 라는 것이 있습니다.HTML을 삭제하고 txt만 남기죠. 그리고 나서 공백이 2개 이상이거나 줄바꿈이 필요 없거나 탭 같은것은 별도 삭제를 해줘야 합니다. 여기서 다루는 함수는 자바스크립트등 몇가지를 더 삭제해 주는 기능입니다.결과 확인 후 본인에게 맞지 않으면 좀 더 추가 해야 될 수 있는데 요즘은 GPT4 이용하면 도움이 많이 됩니다.  /**   * html2txt    *    * @param mixed $document    * @return string|string[]|null    */  function strip_tags_html2txt($document) {    $sear…