PHP에서 Shell_Exec 및 Exec 함수는 모두 외부 명령 또는 스크립트를 실행하는 데 사용되지만 출력 처리 및 실행 동작에는 몇 가지 중요한 차이가 있습니다. 이 두 기능의 사용 시나리오와 장점 및 단점을 이해하는 것은 효율적이고 안전한 코드를 작성하는 데 매우 중요합니다. 이 기사는이 두 기능의 차이점과 실제 응용 프로그램의 적용 가능한 시나리오와 장점 및 단점을 자세히 분석합니다.
shell_exec :
shell_exec 함수는 외부 명령을 실행하고 전체 출력을 반환하는 데 사용됩니다. 이 함수는 명령 (stdout)의 표준 출력을 문자열로 반환합니다. 명령이 실행되지 않거나 출력이 없으면 NULL을 반환합니다.
예:
<span><span><span class="hljs-variable">$output</span></span><span> = </span><span><span class="hljs-title function_ invoke__">shell_exec</span></span><span>(</span><span><span class="hljs-string">'ls -l'</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-variable">$output</span></span><span>;
</span></span> exec :
실행 함수는 외부 명령을 실행하고 실행 결과를 반환합니다. Shell_Exec 과 달리 EXEC 함수는 명령의 출력을 배열로 반환 할 수 있으며 명령 출력의 마지막 줄을 반환 할 수 있으며, 이는 일반적으로 명령의 실행 상태를 처리하는 데 사용됩니다.
예:
<span><span><span class="hljs-variable">$output</span></span><span> = [];
</span><span><span class="hljs-variable">$return_var</span></span><span> = </span><span><span class="hljs-number">0</span></span><span>;
</span><span><span class="hljs-title function_ invoke__">exec</span></span><span>(</span><span><span class="hljs-string">'ls -l'</span></span><span>, </span><span><span class="hljs-variable">$output</span></span><span>, </span><span><span class="hljs-variable">$return_var</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">implode</span></span><span>(</span><span><span class="hljs-string">"\n"</span></span><span>, </span><span><span class="hljs-variable">$output</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-variable">$return_var</span></span><span>; </span><span><span class="hljs-comment">// 명령의 반환 상태 코드</span></span><span>
</span></span> Shell_Exec :
shell_exec 전체 명령의 표준 출력을 문자열로 반환합니다. 전체 출력이 반환되므로 명령 결과를 처리하거나 출력 해야하는 경우에 적합합니다. 그러나 오류 메시지를 반환하지 않으며 명령 실행에 실패하면 오류 코드를 직접 얻을 수 없습니다.
예:
<span><span><span class="hljs-variable">$output</span></span><span> = </span><span><span class="hljs-title function_ invoke__">shell_exec</span></span><span>(</span><span><span class="hljs-string">'cat non_existing_file'</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$output</span></span><span> === </span><span><span class="hljs-literal">null</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Command failed."</span></span><span>;
}
</span></span> exec :
Exec은 표준 출력을 배열로 반환 할 수 있으며 명령 출력을 추가로 처리 할 수 있습니다. 또한 EXEC는 명령의 종료 상태 코드를 반환합니다. 이는 명령이 성공적으로 실행되는지 여부를 결정하는 데 매우 유용합니다. Exec는 상태의 미세한 세분화 처리 및 명령 실행 결과에 적합한 강력한 제어를 제공합니다.
예:
<span><span><span class="hljs-variable">$output</span></span><span> = [];
</span><span><span class="hljs-title function_ invoke__">exec</span></span><span>(</span><span><span class="hljs-string">'ls non_existing_directory'</span></span><span>, </span><span><span class="hljs-variable">$output</span></span><span>, </span><span><span class="hljs-variable">$status_code</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$status_code</span></span><span> !== </span><span><span class="hljs-number">0</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Command failed with status code: <span class="hljs-subst">$status_code</span></span></span><span>";
}
</span></span>Exec 와 Shell_Exec은 모두 외부 명령을 실행할 수 있지만, 특히 사용자 입력을 처리 할 때 잠재적 인 보안 위험을 초래합니다. 여과되지 않은 사용자 입력은 외부 명령을 실행할 때 명령 주입 취약점을 유발할 수 있습니다.
명령 주입 방지 :
이 두 기능을 사용하는 경우 사용자 입력에 특히주의해야합니다. ESCAPESHELLARG 및 ESCAPESHELLCMD를 사용하여 사용자 입력을 피하기 위해 실행시 악의적 인 코드에 의해 명령이 악용되지 않도록하는 것이 가장 좋습니다.
예:
<span><span><span class="hljs-variable">$user_input</span></span><span> = </span><span><span class="hljs-title function_ invoke__">escapeshellarg</span></span><span>(</span><span><span class="hljs-variable">$user_input</span></span><span>);
</span><span><span class="hljs-variable">$output</span></span><span> = </span><span><span class="hljs-title function_ invoke__">shell_exec</span></span><span>(</span><span><span class="hljs-string">"grep <span class="hljs-subst">$user_input</span></span></span><span> file.txt");
</span></span>성능 측면에서 Shell_Exec 과 exec 의 차이는 크지 않지만, 한 가지 주목할 점은 Exec가 라인 당 출력을 반환 할 수 있기 때문에 많은 양의 출력 데이터를보다 유연하게 처리 할 수 있다는 것입니다. Shell_Exec은 전체 출력 문자열을 반환하며 빅 데이터를 처리 할 때 더 많은 메모리를 소비 할 수 있습니다.
shell_exec :
전체 명령 출력을 사용하여 문자열로 반환 해야하는 시나리오에 적합합니다.
명령의 결과에만 관심이 있지만 각 줄의 출력 또는 명령의 상태 코드는 아니에도 shell_exec을 선택할 수 있습니다.
시나리오 예 : CURL 에서 웹 컨텐츠 다운로드와 같은 스크립트 또는 명령의 전체 출력을 가져옵니다.
exec :
명령 출력을 라인별로 처리 해야하는 시나리오에 적합하거나 명령의 종료 상태 코드를 얻어야합니다.
특정 출력 확인 또는 여러 명령 출력과 같은 명령 출력에서 추가 작업을 수행해야 할 때 EXEC는 더 적합합니다.
시나리오 예 : 복잡한 명령 시퀀스 또는 실행 상태 코드를 반환 해야하는 작업을 실행합니다.
| 기능 | 이점 | 결점 | 해당 시나리오 |
|---|---|---|---|
| shell_exec | 전체 명령 출력을 문자열로 반환, 간단하고 사용하기 쉽습니다. | 종료 상태 코드는 반환되지 않으며 출력이 클 때 더 많은 메모리를 소비 할 수 있습니다. | 명령 결과 만 신경 쓰고 세분화 된 출력 분석이 필요하지 않습니다. |
| exec | 지원 여러 줄의 출력 및 종료 상태 코드를 반환합니다. | 사용하기가 약간 복잡하며 처리 배열 및 상태 코드가 필요합니다. | 명령 출력 또는 종속성 상태 코드 판단을 분석해야합니다. |
일반적으로 Shell_Exec 과 Exec는 고유 한 장점과 단점이 있습니다. 선택한 것은 명령 실행 결과에 대한 귀하의 요구에 따라 다릅니다. 명령의 전체 출력에만 관심이있는 경우 Shell_Exec을 사용할 수 있습니다. 출력을 라인별로 처리해야하거나 명령의 종료 상태 코드를 확인 해야하는 경우 EXEC는 더 적합한 선택입니다. 실제 개발에서는 명령 주입의 위험을 방지하고 실제 요구에 따라 적절한 기능을 선택하는 데주의를 기울이는 것이 중요합니다.