>  기사  >  백엔드 개발  >  Linux에서 외부 명령을 실행하는 PHP 방법

Linux에서 외부 명령을 실행하는 PHP 방법

墨辰丷
墨辰丷원래의
2018-05-26 14:28:451343검색

이 글은 주로 Linux에서 PHP가 외부 명령을 구현하는 방법을 소개합니다. 관심 있는 친구들이 참고하면 좋습니다.

디렉토리:

1. PHP에서 외부 명령 호출 소개
2. 보안 문제
3. 시간 초과 문제
4. PHP가 Linux 환경에서 명령을 실행할 때 발생하는 문제

1, PHP에서 외부 명령 호출 소개

PHP에서 외부 명령을 호출하려면 1> 특수 함수 호출, 2> 백틱, 3>popen() 함수를 사용하여 프로세스를 엽니다. 달성 방법:

방법 1: PHP에서 제공하는 특수 함수 사용(4개):

PHP는 외부 명령 실행을 위한 4가지 특수 함수를 제공합니다: exec(), system(), passthru(), shell_exec( )

1) exec()

Prototype: string exec ( string $command [, array &$output [, int &$return_var ] )

설명: exec는 시스템 실행 시 결과를 출력하지 않습니다. 외부 명령이지만 결과의 마지막 행을 반환합니다. 결과를 얻으려면 두 번째 매개변수를 사용하여 지정된 배열로 출력하면 됩니다. 이 배열의 한 레코드는 출력 행을 나타냅니다. 즉, 출력 결과가 20줄이면 이 배열에는 20개의 레코드가 있게 됩니다. 따라서 다른 시스템 외부 명령을 호출한 결과를 반복적으로 출력해야 하는 경우 출력 시 배열 unset($output)을 지우는 것이 가장 좋습니다. 혼동을 방지하기 위해 각 시스템 외부 명령의 결과를 확인합니다. 세 번째 매개변수는 명령 실행 상태 코드를 가져오는 데 사용됩니다. 일반적으로 실행이 성공하면 0이 반환됩니다.

<?php
  exec("dir",$output);
  print_r($output);
?>

2) system()

Prototype: string system ( string $command [, int &$return_var ] )

설명: system과 exec의 차이점은 시스템이 외부에 있다는 것입니다. 실행 시스템 명령을 내리면 주어진 명령을 실행하고 그 결과를 출력하고 반환한다. 두 번째 매개변수는 선택사항이며 명령이 실행된 후 상태 코드를 가져오는 데 사용됩니다.

<?php
system("pwd",$result);
print $result;//输出命令的结果状态码
?>

두 번째 매개변수 결과 상태 코드에 대한 간략한 소개:

0이 반환되면 작업이 성공한 것이고,

Bash에서는 치명적인 신호에 오류가 발생하면 bash는 128을 반환합니다. +신호 번호를 반환 값으로 사용합니다.

명령어를 찾을 수 없으면 127이 반환됩니다.

명령을 찾았지만 명령을 실행할 수 없는 경우 126이 반환됩니다.

또한 Bash 자체는 마지막 명령의 반환 값을 반환합니다.

실행 중 오류가 발생하면 0이 아닌 값이 반환됩니다.

치명적 신호 : 128 + signo
명령을 찾을 수 없음 : 127
실행할 수 없음 : 126
쉘 스크립트가 성공적으로 실행됨 : 마지막 명령 종료 상태를 반환
실행 중 치명적 : 0이 아닌 값을 반환

3) passthru()

Prototype: void passthru ( string $command [, int &$return_var ] )

설명: passthru와 시스템의 차이점, passthru는 어떤 값도 반환하지 않고 결과를 브라우저에 직접 출력합니다. , 이미지 데이터와 같은 이진 데이터를 출력할 수 있습니다. 두 번째 매개변수는 선택사항이며 상태 코드입니다.

<?php
header("Content-type:image/gif");
passthru("/usr/bin/ppm2tiff /usr/share/tk8.4/demos/images/teapot.ppm");
?>

4) shell_exec()

프로토타입: string shell_exec ( string $cmd )

설명: $cmd

<?php
$output = shell_exec(&#39;ls -lart&#39;);
echo "<pre class="brush:php;toolbar:false">$output
"; ?>

명령을 직접 실행하세요. 방법 2: 역방향 skimming No.

프로토타입: 시스템 외부 명령을 실행하기 위한 백틱 `(같은 키에 ~ 사용)

설명: 이 방법을 사용하여 시스템 외부 명령을 실행하는 경우 shell_exec 기능을 사용할 수 있는지 확인하고, 그렇지 않으면 이 방법을 사용하세요. 백틱은 시스템 외부 명령을 실행하는 데 사용할 수 없습니다.

<?php
  echo `dir`;
?>

방법 3: popen() 함수를 사용하여 프로세스

프로토타입: 리소스 popen( 문자열 $command , 문자열 $mode )

설명: 명령과 상호 작용할 수 있습니다. 이전에 소개한 방법은 단순히 명령을 실행할 수만 있을 뿐 명령과 상호 작용할 수는 없습니다. 예를 들어, 시스템 사용자를 추가할 때 su를 호출하여 현재 사용자를 루트 사용자로 변경해야 하는 경우가 있습니다. su 명령은 명령줄에 루트 암호를 입력해야 합니다. 이 경우 앞에서 언급한 방법을 사용하는 것은 당연히 불가능합니다.

popen() 함수는 프로세스 파이프를 열어 주어진 명령을 실행하고 읽고 쓸 수 있는 파일 핸들을 반환합니다. 반환 값은 파일 포인터를 반환하는 fopen() 함수와 동일합니다. 열기(읽기 또는 쓰기)에 단일 모드를 사용하지 않는 한 pclose() 함수를 사용하여 닫아야 합니다. 이 포인터는 fgets(), fgetss(), fwrite()에 의해 호출될 수 있습니다. 오류가 발생하면 FALSE를 반환합니다.

<?php
error_reporting(E_ALL);
 
/* Add redirection so we can get stderr. */
$handle = popen(&#39;/path/to/executable 2>&1&#39;, &#39;r&#39;);
echo "&#39;$handle&#39;; " . gettype($handle) . "\n";
$read = fread($handle, 2096);
echo $read;
pclose($handle);
?>

2. 보안 관련 사항:

WEB 프로그램 개발에는 기본적으로 PHP가 사용되기 때문에 보안은 사람들이 중요하게 생각하는 부분이 되었습니다.

그래서 PHP 설계자는 PHP에 안전 모드라는 문을 추가했습니다.

php.ini에서 safe_mode = On으로 설정

如果运行在安全模式下,那么PHP脚本中将受到如下四个方面的限制:

执行外部命令
在打开文件时有些限制
连接MySQL数据库
基于HTTP的认证

在安全模式下,只有在特定目录中的外部程序才可以被执行,对其它程序的调用将被拒绝。这个目录可以在php.ini文件中用safe_mode_exec_dir指令,或在编译PHP 是加上–with-exec-dir选项来指定,默认是/usr/local/php/bin。

当你使用这些函数来执行系统命令时,可以使用escapeshellcmd()和escapeshellarg()函数阻止用户恶意在系统上执行命令,escapeshellcmd()针对的是执行的系统命令,而escapeshellarg()针对的是执行系统命令的参数。这两个参数有点类似addslashes()的功能。

三、关于超时问题

当执行命令的返回结果非常庞大时,可以需要考虑将返回结果输出至其他文件,再另行读取文件,这样可以显著提高程序执行的效率。

如果要执行的命令要花费很长的时间,那么应该把这个命令放到系统的后台去运行。但在默认情况下,象system()等函数要等到这个命令运行完才返回(实际上是在等命令的输出结果),这肯定会引起PHP脚本的超时。解决的办法是把命令的输出重定向到另外一个文件或流中,如:

<?php
system("/usr/local/bin/order_proc > /tmp/abc ");
?>

但我调用的DOS命令需要几分钟的时间,而且为了批处理不能简单的把结果写入文件了事,要顺序执行以下的程序

PHP设置了调用系统命令的时间限制,如果调用命令超时,虽然这个命令还是会被执行完,但PHP没有得到返回值,被终止了(最可恨的是,不显示任何错误)

修改php.ini并重启Apache以允许系统命令运行更长的时间

max_execution_time = 600

四、关于PHP运行linux环境中命令出现的问题

php一般是以apache用户身份去执行的,也可能是www用户,把apache加入到存储你文件的父文件夹属组里去,然后改该父文件夹权限为775,这样属组成员就有写的权限,而apache属于这个组就可以改写该目录下所有文件的权限。

例如:chown www:www dirName

这样dirName目录才能被php所控制

注意:改apache/php的运行用户方法不安全

另外即使文件或目录已经是www,php的安全设置也都照顾到,一些自己安装linux的命令仍然可能无法运行,例如我曾经安装的ffmpeg软件,原因就是linux的运行权限问题,即使ffmpeg有www权限设置,但由于ffmpeg所依赖的库文件是不允许www用户运行,所以php运行此程序仍然会报127或126错误,通过 ldd 命令可以查看ffmpeg命令依赖的库情况。

这个时候就必须对ffmpeg的依赖库经行设置。具体方法属于linux管理中的话题,这里不就讨论了。

以上就是本文的全部内容,希望对大家的学习有所帮助。


相关推荐:

node.js 命令行工具使用详解

node 命令方式启动修改端口步骤详解

PHP在linux上执行外部命令的方法

위 내용은 Linux에서 외부 명령을 실행하는 PHP 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.