PHP에서 exec 함수의 경우 쉘 명령어(shell)를 수행할 수 있도록 도와주는 함수이며 그만큼 사용시에 보안에 신경 써야한다. 대부분 가공된 데이터를 기준 한정된 코드로 가공하여 많이 사용하게 되는데 특정 명령어를 사용할때 출력되는 내용이 전체가 아닌 마지막 부분만 노출되는 경우가 있다. 분명 쉘(shell)에서 입력할때는 정상 출력 되지만 PHP exec 함수를 사용할 경우엔 마지막 출력값만 배열에 저장되는 문제가 있다.   

 

exec 함수를 통핸 `php -l` 명령어 실행예제
<?php 
$filePath = '/home/dev/web/test.php'; // 파일 절대 경로
exec("php -l ".$filePath, $output); // php -l 쉘 명령어
print_r($output);

 

| 결과 

Array
(
    [0] => Errors parsing /home/dev/web/test.php
)

 

위의 쉘(Shell)명령어인`php -l` 의 경우 PHP의 문법체크 명령어로 에러가 없을 경우엔 `No syntax errors detected in 파일명` 으로 노출되기때문에 처음엔 모르고 넘어갔는데 막상 파일 문법 에러가 발생되니 상세 에러값 없이 마지막 결과값만 출력되고 있다는걸 알게되 었다. 이럴때는 아래와 같은 방법으로 해결이 가능하다.  (물론 php.ini 에서 display_errors=On 으로 설정함으로 써 해결이 가능하다.)

<?php 
$filePath = '/home/dev/web/test.php'; // 파일 절대 경로
exec("php -l ".$filePath." 2>&1", $output); // php -l 쉘 명령어
print_r($output);

 

| 결과

Array
(
    [0] => PHP Parse error:  syntax error, unexpected '$response' (T_VARIABLE) in /home/dev/web/test.php on line 7
    [1] => Errors parsing /home/dev/web/test.php
)

 

위의 소스코드를 보면 2>&1 이 추가된것을 알 수 있다. 해당 옵션은 간단하게 말해 오류가 있을 경우에도 출력을 하겠다는 옵션으로 이해하면 되고 자세한 설명은 맨 하단 참고 사이트에서 살펴보면 도움이 될것이다. 

 

참고사이트 (2>&1 관련)
 
쉘스크립트에서 이따금씩 사용되는 2>&1 이해하기
이런저런 쉘스크립트를 보다면 스크립트의 문장 끝부분이 다음과 같은 구문을 종종 보게된다.
blogger.pe.kr/369/

 

참고로 앞서 언급했다시피 php -l 명령어 자체가 PHP CGI 설정에 따른 환경 변수를 참고하기 때문인지는 모르나 php.ini 파일의 display_errors=On 으로 설정하면 원하는 입력값을 얻을 수 있다. 다만 에러 설정을 기본 노출하는건 서비스 운영환경에서는 보안상 좋지 않기때문에 또다른 방법으로 해결이 가능하다. 해당 명령어는 아래와 같다. 

<?php 
$filePath = '/home/dev/web/test.php'; // 파일 절대 경로
exec("php -l -d display_errors=On ".$filePath, $output); // php -l 쉘 명령어
print_r($output);

 

위의 결과는 동일하게 에러를 확인 가능하며 추가된 부분은 -d 옵션부분인데 이는 환경변수(.ini) 설정값을 지정 가능한 옵션으로 쉘 명령어에서만 줄 수 있는 유용한 옵션이니 참고하길 바란다.