[PHP] cmd (커맨드 명령어)를 실행하는 방법


Development note/PHP  2020. 1. 14. 09:00

안녕하세요. 명월입니다.


이 글은 PHP에서 cmd (커맨드 명령어)를 실행하는 방법에 대한 글입니다.


Java나 C#에서도 cmd 명령어를 사용하는 방법에 대해 설명한 적이 있습니다.

링크 - [Java] cmd 명령어를 실행하기 위한 방법 (Process 클래스)

링크 - [C#] C#으로 CMD 명령어 및 배치 파일 연동


PHP에서도 cmd명령어를 사용하는 방법이 있습니다. 그런데 Java와 C#과 다르게 세션을 유지시켜 주는 방법에 대해서는 없는 것 같네요. PHP의 특성상 데이터가 pointer 참조식이 아닌 값 참조 식이다 보니 그런 것같 습니다.(개인 생각..)

<?php
  $data = shell_exec("dir");
  // euc-kr의 인코딩을 utf-8로 변환한다.
  $data =  mb_convert_encoding($data, "UTF-8", "euc-kr");
  // htmlspecialchars는 html에서 읽혀지는 <, >, &, ", '의 특수 기호를 html코드로 변환한다.
  echo "<pre>".htmlspecialchars($data)."</pre>";
?>

shell_exec의 함수에 cmd 명령어를 넣어서 실행하면 $data1에는 커맨더의 결과가 return됩니다.

cmd의 경우는 인코딩 셋이 utf-8가 아니기 때문에 encoding셋을 변환해서 출력할 필요가 있습니다.


윈도우의 경우는 cmd에서 chcp로 확인할 수 있고 linux의 경우는 locale로 인코딩 타입을 확인할 수 있습니다.

링크 - https://docs.microsoft.com/en-us/windows/win32/intl/code-page-identifiers

링크 - https://www.osetc.com/en/centos-7-rhel-7-change-the-system-locale.html


일단 저는 window에서 확인하는 예제이니 chcp로 확인하겠습니다.

저의 경우는 cmd가 euc-kr로 설정이 되어 있습니다.

apache에서 위 명령어를 실행시켜 보겠습니다.

위 명령어에 dir를 치니 작성이 됩니다.


이번에는 조금 웹 페이지에서 cmd를 사용할 수 있게끔 화면을 만들어 보겠습니다.

<!DOCTYPE html>
<html>
<head>
	<title>title</title>
  <meta charset="utf-8">
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
</head>
<body>
  <style>
    .cmd-area {
      margin:50px;
    }
    .cmd-area pre {
      border: 1px solid #000;
      height: 500px;
      overflow: auto;
    }
  </style>
  <!-- 커맨드 area이다. -->
  <div class="cmd-area">
    <!-- 커맨드를 보낼 경우 결과를 표시할 영역이다. -->
    <pre class="cmd-result"></pre>
    <!-- 커맨드를 쓰고 버튼을 누르면 서버로 커맨더 명령어가 전송이 된다. -->
    <input type="text" id="cmd" style="width:70%"> <button id="exec">cmd exec</button>
  </div>
  <script>
    function insertCmdResult(msg){
      var obj = $(".cmd-result");
      data = obj.html();
      data += msg + "\n";
      obj.html(data);
      obj.scrollTop(obj[0].scrollHeight);
    }
    $("#exec").on("click", function(){
      // cmd.php에 명령어를 보냅니다.
      var ajax = $.ajax({
        type: "POST",
        url: "cmd.php",
        dataType: 'json',
        data: {"cmd" : $("#cmd").val() }
      });
      // cmd.php의 응답이 오면 {"result":"결과"}의 형식으로 cmd의 결과가 나온다. 그 결과를 결과 영역에 표시한다.
      ajax.done(function(data){
        insertCmdResult(data.result);
      });
      // cmd.php에 에러가 발생하면 결과 영역에 error를 표시한다.
      ajax.fail(function(){
        insertCmdResult("error!!!");
      });
      // 응답 요청이 끝나면 cmd textbox를 클리어 한다.
      ajax.always(function(){
         $("#cmd").val("");
      });
    });
  </script>
</body>
</html>
<?php
  $ret = [];
  $ret["result"] = "";
  // ajax가 POST형식으로 요청이 오면 명령어를 실행한다.
  if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $data = shell_exec($_POST["cmd"]);
    $data = mb_convert_encoding($data, "UTF-8", "euc-kr");
    // 결과를 $ret변수의 result키로 값을 넣는다.
    $ret["result"] = htmlspecialchars($data);
  }
// json형식으로 변환한다.
?>
<?=json_encode($ret)?>

shell_exec와 같은 역활을 하는 함수로 exec도 있습니다.

참조 - https://www.php.net/manual/en/function.shell-exec.php

참조 - https://www.php.net/manual/en/function.mb-convert-encoding.php

참조 - https://www.php.net/manual/en/function.htmlspecialchars.php

참조 - https://www.php.net/manual/en/function.exec.php


php에서는 이 shell의 세션이 유지가 되지 않네요. 즉, cmd에서 디렉토리 이동을 해도 root, 즉 htdocs의 상위 폴더로 이동이 되지 않습니다.

세션이 유지가 되지 않는 다는 뜻입니다. 사실 php에서 세션을 받는 다 해도 어떻게 그 세션 값을 넘길 것이며, 세션을 해제할 것인지 조금 복잡해 지기는 하겠네요. 웹 세션에 넣어서 관리를 하는 방법도 있겠습니다만, 브라우져마다 세션이 달라지고 역시 메모리 릭(누수)가 발생할 위험이 크겠습니다.


여기까지 PHP에서 cmd (커맨드 명령어)를 실행하는 방법에 관한 설명이었습니다.


궁금한 점이나 잘못된 점이 있으면 댓글 부탁드립니다.