리눅스 cron 스케줄러에 등록된 프로그램에서 특정단어 찾기 > PHP
PHP

리눅스 cron 스케줄러에 등록된 프로그램에서 특정단어 찾기

조회 264회 댓글 0건
  • 현재 페이지 주소 복사
  • 페이스북으로 공유
  • X 로  공유
  • 트위터로  공유
  • 네이버 블로그로 공유
  • 네이버 카페 공유하기
  • 네이버 라인 공유하기
  • 네이버 밴드 공유하기
  • 링크드인으로 공유하기
  • 핀터레스트에 공유하기

스케줄러에 등록된 프로그램에서 특정 함수 사용하는것이 있을 경우 어느 프로그램에서 사용하는지 알고 싶어서 만들게 된 프로그램 입니다.

사용은 이렇게 했지만 반드시 그럴 필요는 없지요.




특정 약간 수정해서 특정 디렉토리에 있는것을 찾을 수도 있고. 웬만한것은 쉘스크립트로도 가능할듯.

 

   
    // cron_php_word_search_functions.php
    // 설명: crontab/스케줄러 파일들을 읽어서 php 파일 경로를 찾아
    //       해당 php 파일 내용에 미리 지정한 단어들이 있는지 확인합니다.

    /**
    * 크론 파일들을 전체 스캔하고 결과 출력
    * @param array $aSearchWords 찾을 단어 배열
    * @param array|null $aScanPaths 사용자 지정 경로 배열 (없으면 기본값 사용)
    * @return void
    */
    function wordsearch_run(array $aSearchWords, array $aScanPaths = null): void
    {
        // 기본 검사할 크론 경로
        $aDefaultPaths = [
            '/var/spool/cron',
            '/var/spool/cron/crontabs',
            // '/etc/cron.d',
            // '/etc/crontab',
            // '/etc/cron.daily',
            // '/etc/cron.hourly',
            // '/etc/cron.weekly',
            // '/etc/cron.monthly',
        ];

        $aScanPaths = $aScanPaths ?? $aDefaultPaths;
        $aCronFiles = [];
       
        // 크론 파일 목록 수집
        foreach ($aScanPaths as $sPath) {
            if (is_dir($sPath)) {
                $aItems = scandir($sPath);
                foreach ($aItems as $sItem) {
                    if ($sItem === '.' || $sItem === '..') continue;
                    $sFull = rtrim($sPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $sItem;
                    if (is_file($sFull)) $aCronFiles[] = $sFull;
                }
            } elseif (is_file($sPath)) {
                $aCronFiles[] = $sPath;
            }
        }

        if (empty($aCronFiles)) {
            echo "검사할 크론 파일이 없습니다. (경로 확인 필요)\n";
            return;
        }

        // 각 크론 파일 처리
        foreach ($aCronFiles as $sCronFile) {
            echo "=================================================================\n";
            echo "크론 파일: {$sCronFile}\n";
           
            // 크론 파일 읽기
            if (!is_file($sCronFile) || !is_readable($sCronFile)) {
                echo "  오류: 파일을 읽을 수 없습니다 (권한 또는 파일 아님).\n";
                continue;
            }
           
            $sCronContent = file_get_contents($sCronFile);
            if ($sCronContent === false) {
                echo "  오류: 파일 내용을 읽을 수 없습니다.\n";
                continue;
            }

            $aLines = preg_split('/\R/u', $sCronContent);
            $aPhpPaths = [];

            // 크론 라인에서 PHP 경로 추출
            foreach ($aLines as $sLine) {
                $sLine = trim($sLine);
                if ($sLine === '' || $sLine[0] === '#') continue;

                $sPattern = '/(\/[^\s;|&<>]+?\.php)(?=\s|$)/';
                if (preg_match_all($sPattern, $sLine, $aMatches)) {
                    foreach ($aMatches[1] as $sMatch) {
                        if (!in_array($sMatch, $aPhpPaths)) $aPhpPaths[] = $sMatch;
                    }
                }
            }

            if (empty($aPhpPaths)) {
                echo "  -> 이 크론 파일에서 찾은 php 경로가 없습니다.\n";
                continue;
            }

            // 각 PHP 파일 검사
            foreach ($aPhpPaths as $sPhpPath) {
                echo "  PHP 경로: {$sPhpPath}\n";
               
                $bExists = is_file($sPhpPath);
                echo "    존재: " . ($bExists ? '' : '아니오') . "\n";
               
                if (!$bExists) {
                    echo "    발견된 단어: 없음\n";
                    echo PHP_EOL;
                    continue;
                }
               
                $bReadable = is_readable($sPhpPath);
                echo "    읽기 가능: " . ($bReadable ? '' : '아니오') . "\n";
               
                if (!$bReadable) {
                    echo "    발견된 단어: 없음\n";
                    echo PHP_EOL;
                    continue;
                }

                // PHP 파일에서 단어 검색
                $sPhpContent = file_get_contents($sPhpPath);
                $aFoundWords = [];
                $aWordLines = [];

                foreach ($aSearchWords as $sWord) {
                    $iCount = substr_count($sPhpContent, $sWord);
                    if ($iCount > 0) {
                        $aContentLines = preg_split('/\R/u', $sPhpContent);
                        $aLinesFound = [];
                        foreach ($aContentLines as $i => $sContentLine) {
                            if (stripos($sContentLine, $sWord) !== false) { // 대소문자 무시 검색
                                $aLinesFound[] = $i + 1;
                            }
                        }
                        $aFoundWords[$sWord] = $iCount;
                        $aWordLines[$sWord] = $aLinesFound;
                    }
                }

                // 결과 출력
                if (!empty($aFoundWords)) {
                    echo "    발견된 단어: \n";
                    foreach ($aFoundWords as $sWord => $iCount) {
                        $aLines = $aWordLines[$sWord] ?? [];
                        $sLines = implode(', ', $aLines);
                        echo "      - {$sWord} : {$iCount}회 (라인: {$sLines})\n";
                    }
                } else {
                    echo "    발견된 단어: 없음\n";
                }
                echo PHP_EOL;
            }
        }
        echo "\n완료.\n";
    }

    // ---------------- 실행 예제 ----------------
    // 사용법: wordsearch_run(['https', 'twssp']);
    // 또는 경로를 지정하여: wordsearch_run(['https', 'twssp'], ['/custom/path']);

    // 예제 실행
    wordsearch_run(['https', 'twssp']);

 



  • 현재 페이지 주소 복사
  • 페이스북으로 공유
  • X 로  공유
  • 트위터로  공유
  • 네이버 블로그로 공유
  • 네이버 카페 공유하기
  • 네이버 라인 공유하기
  • 네이버 밴드 공유하기
  • 링크드인으로 공유하기
  • 핀터레스트에 공유하기
전체 237건 1 페이지
  • profile_image PHP 설치 되어 있지 아니하여 윈도우PC에 최신버전으로 설치버전은 설치 할 때마다 다르기 때문에 본인이 사용하려는버전을 선택 하면 됩니다.     > 현대적인? 방법으로 설치함.       예전에 압축해 놓은것 풀고 path 설정하고 했던 그런 방법을 쓰지 않고 간단하게 설치가 되었다.      winget install PHP.PHP.8.5    > 아래 명령으로 설치된 위치를 찾음      where php    > php.ini-production…
  • profile_image OP캐쉬 사용하면 괜찮아 보다는 저 같은 경우는 사용하지 않아도 괜찮아를 더 좋아 합니다.▷ 솔리드 캐시(SOLID CACHE)란?솔리드 캐시는 간단히 말해 "비싼 RAM(REDIS) 대신 저렴하고 넉넉한 디스크(DB)에 캐시를 저장하는 전략"으로 원래 루비 온 레일즈(RUBY ON RAILS) 커뮤니티에서 제안된 방식이지만 본질은 어떤 언어에서든 적용 가능한 실용적인 캐싱 철학임.▷ 핵심 철학: "ssd는 생각보다 훨씬 빠르다"과거에는 디스크가 너무 느려서 무조건 데이터를 ram(REDIS MEMCACHED)에 올려야 했지만 지금은 nvme ssd 같은 초고속 저장 장치가 보편화되었습니다. 굳이 복잡하게 별도의 메모리…
  • profile_image MyISAM은 SELECT가 빠르고 InnoDB는 느리다그런 경우도 있고 아닌 경우도 있기 때문에 어떤 용도로 사용하느냐에 따라서 다를 수 있습니다.그리고 처음 데이터 넣은 다음 select만 90% 이상이고 테이블 사용이 업데이트나 인서트는 적은 경우인지 불특정 다수에게 서비스 하기 때문에 불특정한 row를 가져와서 보여줘야 하는것인지에 다를 수 있는 것입니다. 가장 큰 차이: 데이터와 인덱스 구조→ MyISAM  - 데이터 파일(.MYD) 과 인덱스 파일(.MYI) 이 분리됨  - 인덱스 → 데이터 파일을 다시 읽는 구조  - 동작흐름: PK 인덱스 탐색 (.MYI) -> 데이터 위치…
  • profile_image 데이터베이스를 사용하다 보면 이미 존재하는 데이터인지 확인한 후 INSERT 또는 UPDATE를 해야 하는 상황을 자주 만나게 됩니다.이때 매우 유용한 문법이 바로 INSERT ... ON DUPLICATE KEY UPDATE입니다.즉, 쿼리 한번으로 해결 된다는 의미 인데 아무곳에서나 사용 가능한것은 아니고 키 중복이 발생하는 부분에서만 사용 하는 것입니다.그렇기 때문에 unique의 특성을 모르시는 분은 사용 하면 안되겠지요.  장점- 쿼리 수 감소: SELECT → INSERT/UPDATE 두 번 쿼리 날릴 필요 없음- 동시성 문제 감소: SELECT 후 INSERT 방식보다 Race Condition 발…
  • profile_image 웹서버에 접근하는 X-Forwarded-For란?X-Forwarded-For(XFF)는 HTTP 헤더로 클라이언트가 프록시나 로드 밸런서를 거쳐 웹 서버에 접속할 때 원래 클라이언트의 IP 주소를 식별하기 위해 사용 됩니다.로그밸런스도 프록시서버의 변형된 형태가 있기 때문에 쉽게 프록시 서버라고 생각을 하면 쉽습니다.일반적으로 웹 서버는 직접 연결된 IP만 볼 수 있는데 프록시 뒤에 있으면 프록시 서버의 IP만 보이게 되는데 이런 경우 XFF 헤더가 실제 사용자 IP를 전달하는 역할을 합니다. ▷ 헤더 형식X-Forwarded-For: 클라이언트IP 프록시1 프록시2 ...여러 프록시를 거치면 쉼표로 구분되어 …
  • profile_image ifconfig는 초기 한번 정도만 사용하고 interface configuration의 약자로 리눅스/유닉스 시스템에서 네트워크 인터페이스를 설정하고 확인하는 명령어입니다.▷ ifconfig 주요 용도1. 네트워크 인터페이스 정보 조회  - 현재 활성화된 네트워크 인터페이스 목록 확인  - 각 인터페이스의 IP 주소, MAC 주소, 서브넷 마스크 확인  - 네트워크 통계 정보 (전송/수신 패킷 수, 에러 등) 확인2. 네트워크 인터페이스 설정  - IP 주소 할당 및 변경  - 서브넷 마스크 설정  - 브로드캐스트 주소 설정  - MTU(Maximum Tr…
  • profile_image 결론부터 말하면 느리게 다운로드 처리 하는 방식에 대한 것입니다.왜? 느리게 다운로드가 필요한가 하면 지연을 시키면 트래픽이 평탄화 되는 효과가 있는데 갑자기 순간적으로 팍 튀는 그런 현상을 없애기 위해서 필욯나 방법중 하나 입니다. 원리는 간단하며 읽은 만큼 내보내고 약간 지연 시키는 방식 입니다.    /**     * 청크 단위로 지연시키면서 파일 다운로드 (대용량 파일용)     *     * @param string $filePath 다운로드할 파일 경로     * @param …

상업적 이용 금지. 컨텐츠는 개인 용도로만 사용이 가능 합니다.