PHP shell_exec () 대 exec ()


345

와의 차이점을 이해하기 위해 고심 shell_exec()하고 있습니다 exec()...

exec()서버 측 명령을 실행 하는 데 항상 사용 shell_exec()했습니까?

shell_exec()단지 속기 exec()? 더 적은 매개 변수를 가진 동일한 것으로 보입니다.


2
차이를 볼 수있는 좋은 예는 이러한 명령을 시도하는 것입니다 : date, whoami, ifconfig, netstat.

다른 함수들도 있습니다 : system (), passthru ()…이 관련 질문 , 특히이 답변을보십시오 .
Gras Double

답변:


353

shell_exec모든 출력 스트림을 문자열로 반환합니다. exec기본적으로 출력의 마지막 줄을 반환하지만 모든 출력을 두 번째 매개 변수로 지정된 배열로 제공 할 수 있습니다.

보다


21
종료 값과 모든 출력이 필요한 경우 "shell_exec"대신 "exec"를 사용하는 것이 좋습니다. 출력 매개 변수를 "exec"에 전달하자마자 출력의 모든 줄로 채워질 것입니다. "exec"는 "shell_exec"등을 모두 할 수 있습니다. :)
Preexo

4
@ daniel-a-white 나는 이것이 오래된 것임을 알고 있지만 인기가 있으므로 @preexo의 의견을 반영하도록 답변을 편집해야합니다-exec () 또한 선택적 매개 변수를 사용하면 전체 출력을 반환 할 수 있습니다 . 또한, 관련이없는, 누군가해야 벤치 마크 두 개의 명령이 더 @preexo 말했듯이 becase 인보고 "나에게 보인다 exec()[할] 수있는 모든 shell_exec()[캔,] 더 :) "
SimpleAnecdote

77

차이점은 다음과 같습니다. 마지막 줄 바꿈에 유의하십시오.

> shell_exec('date')
string(29) "Wed Mar  6 14:18:08 PST 2013\n"
> exec('date')
string(28) "Wed Mar  6 14:18:12 PST 2013"

> shell_exec('whoami')
string(9) "mark\n"
> exec('whoami')
string(8) "mark"

> shell_exec('ifconfig')
string(1244) "eth0      Link encap:Ethernet  HWaddr 10:bf:44:44:22:33  \n          inet addr:192.168.0.90  Bcast:192.168.0.255  Mask:255.255.255.0\n          inet6 addr: fe80::12bf:ffff:eeee:2222/64 Scope:Link\n          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1\n          RX packets:16264200 errors:0 dropped:1 overruns:0 frame:0\n          TX packets:7205647 errors:0 dropped:0 overruns:0 carrier:0\n          collisions:0 txqueuelen:1000 \n          RX bytes:13151177627 (13.1 GB)  TX bytes:2779457335 (2.7 GB)\n"...
> exec('ifconfig')
string(0) ""

백틱 연산자의 사용법 은과 동일합니다 shell_exec().

업데이트 : 마지막으로 설명해야합니다. 몇 년 후이 답변을 보면 왜 그것이 비 었는지 모르겠습니다! Daniel은 위에서 설명했습니다 exec. 마지막 줄만 반환 하기 때문에 ifconfig마지막 줄은 비어 있습니다.


명령에 오류가 발생하면 어떻게 되나요? 오류가 발생했습니다 / 해당 파일이나 디렉토리가 없지만 변수에 어떻게 캡처 할 수 있습니까 ????
Happy Coder

@AlwinAugustin : 응? STDERR에 기록 될 수 있습니다. 2>&1리눅스 머신이라면 STDERR을 STDOUT으로 리다이렉션하기 위해 커맨드의 끝에 추가해보십시오 .
mpen

나는 또한 그것을 추가했다. 그러나 여전히 값으로 0을 얻고 있습니다. 하나의 wc -l 명령을 사용했는데 파일이 없으면 해당 파일이나 디렉토리가 없음이라는 오류 메시지가 표시되어야합니다.
Happy Coder

50

shell_exec-쉘을 통해 명령을 실행 하고 완전한 출력을 문자열로 반환

exec -외부 프로그램을 실행하십시오.

차이점은 shell_exec출력을 반환 값으로 얻는다 는 것입니다 .


4
간결한 요약! exec출력의 마지막 행 을 리턴 한다는 점에 유의해야 합니다. 원하는 경우, 전체 출력을 캡처하기 위해 두 번째 매개 변수로 배열을 전달하고 오류 검사에 사용될 수있는 쉘 명령의 리턴 값을 캡처하기 위해 세 번째 매개 변수로 정수를 선택적으로 전달할 수 있습니다. 가장 큰 단점 shell_exec은 명령이 실패하거나 출력을 생성하지 않으면 null을 반환하므로 반환 값을 오류 검사에 안정적으로 사용할 수 없다는 것입니다.
Sean the Bean

38

여기서 다루지 않은 몇 가지 차이점 :

  • exec ()를 사용하면 출력 행 배열을 수신 할 선택적 param 변수를 전달할 수 있습니다. 경우에 따라 특히 명령 출력이 이미 테이블 형식 인 경우 시간이 절약 될 수 있습니다.

비교:

exec('ls', $out);
var_dump($out);
// Look an array

$out = shell_exec('ls');
var_dump($out);
// Look -- a string with newlines in it

반대로, 명령의 출력이 xml 또는 json 인 경우 입력을 다른 형식으로 후 처리해야하므로 각 행을 배열의 일부로 갖는 것은 원하는 것이 아닙니다.이 경우 shell_exec를 사용하십시오 .

shell_exec는 * nix에 사용 된 백틱 연산자의 별명임을 지적 할 가치가 있습니다.

$out = `ls`;
var_dump($out);

exec는 실행 된 명령의 리턴 코드를 제공하는 추가 매개 변수도 지원합니다.

exec('ls', $out, $status);
if (0 === $status) {
    var_dump($out);
} else {
    echo "Command failed with status: $status";
}

shell_exec 매뉴얼 페이지에서 언급 한 것처럼 실제로 실행중인 명령의 리턴 코드가 필요한 경우 exec를 사용할 수 밖에 없습니다.


3
또한 : exec명령의 리턴 코드 ( &$return_var매개 변수 를 통해 ) 를 가져올 수 있지만 명령 shell_exec을 얻는 방법은 없습니다.
Mark Amery

수락 된 답변도 정확하지만 내 의견으로는이 답변이 더 중요합니다. 아마도 가장 좋은 대답은 두 가지의 조합 일 것입니다.
UncaAlby
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.