PHP 执行外部命令函数:exec()、system()、passthru()、shell

您所在的位置:网站首页 Shell执行bcp命令 PHP 执行外部命令函数:exec()、system()、passthru()、shell

PHP 执行外部命令函数:exec()、system()、passthru()、shell

2024-06-28 07:45| 来源: 网络整理| 查看: 265

PHP内置函数,提供了4种方法执行系统外部命令:

exec()、system()、passthru()、 shell_exec()

 

查看命令函数配置

在开始介绍前,先检查下php配置文件php.ini中是有禁止这是个函数

vim /etc/php.ini   或    vim /usr/local/php/lib/php.ini

php.ini 默认配置文件中是不禁止你调用执行外部命令的函数的。

找到 disable_functions,正常开启的配置为 disable_functions =  ,具体如下:

1

2

3

4

5

; This directive allows you to disable certain functions for security reasons.

; It receives a comma-delimited list of function names. This directive is

; *NOT* affected by whether Safe Mode is turned On or Off.

; http://php.net/disable-functions

disable_functions =

如果“disable_functions=”后面有接上面四个函数,将其删除,并重启 httpd 或  php-fpm

 

 

exec()

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

说明:

第一个参数, $command 是要执行的命令,例如: "ls -l"

第二个参数,$output 是command执行输出的结果,以数组格式存储

第三个参数,$return_var,用于保存command执行状态,0 - 成功,非零 - 失败

返回值,为command执行结果的最后一行

 

示例:

1

2

3

4

5

6

7

8

9

10

11

12

// exec

$retval = null;

$res = null;

$res_array = array();

 

$cmd = "/usr/bin/curl -k --head 'https://mimvp.com'";

$res = exec($cmd, $res_array, $retval);

 

echo " exec result:";

var_dump($retval);      // 0 (返回的状态, 0 - 成功, 非零 - 失败)

var_dump($res);         // ''

var_dump($res_array);   // 返回结果数组

运行结果:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

exec result:

/Users/homer/mimvp_site/api/header2.php:55:int 0

/Users/homer/mimvp_site/api/header2.php:56:string '' (length=0)

/Users/homer/mimvp_site/api/header2.php:57:

array (size=9)

  0 => string 'HTTP/2 200' (length=10)

  1 => string 'server: nginx' (length=13)

  2 => string 'date: Tue, 26 Dec 2017 01:52:11 GMT' (length=35)

  3 => string 'content-type: text/html; charset=UTF-8' (length=38)

  4 => string 'vary: Accept-Encoding' (length=21)

  5 => string 'vary: Accept-Encoding' (length=21)

  6 => string 'vary: mimvp-home-bj2' (length=20)

  7 => string 'vary: mimvp-homes-bj2' (length=21)

  8 => string '' (length=0)

从结果看

1)第二行结果 $retval 为状态 0 ,表示 cmd 命令执行成功

2)第三行结果 $res 为空字符串 '',表示 cmd 命令执行返回结果的最后一行,见 $res_array 数组最后一行(第八行)为空

3)第五行结果 $res_array 保存了完整的 cmd 命令执行结果,说明第二个参数保存 exec 执行结果

知识点:

exec 执行系统外部命令时,只返回结果的最后一行,如果想得到完整的执行结果,需要使用第二个参数,让其输出到指定的数组,此数组一个记录代表输出的一行,即如果输出结果有20行,则这个数组就有20条记录。所以,如果你需要反复输出调用不同系统外部命令的结果,最好在输出每一条系统外部命令结果时清空这个数组 $res_array = array(),以防混乱。第三个参数用来取得命令执行的状态码,通常执行成功都是返回0

 

 

system()

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

说明:

第一个参数, $command 是要执行的命令,例如: "ls -l"

第二个参数,$return_var,用于保存command执行状态,0 - 成功,非零 - 失败

返回值,为command执行结果的最后一行(system 和 exec 类似),失败返回 FALSE

 

示例:

1

2

3

4

5

6

7

8

9

10

// system

$retval = null;

$res = null;

 

$cmd = "/usr/bin/curl -k --head 'https://mimvp.com'";

$res = system($cmd, $retval);

 

echo " system result:";

var_dump($retval);      // 0 (返回的状态, 0 - 成功, 非零 - 失败)

var_dump($res);         // ''

运行结果:

1

2

3

4

5

cmd : /usr/bin/curl -k --head 'https://mimvp.com'HTTP/2 200 server: nginx date: Tue, 26 Dec 2017 01:52:11 GMT content-type: text/html; charset=UTF-8 vary: Accept-Encoding vary: Accept-Encoding vary: mimvp-home-bj2 vary: mimvp-homes-bj2

 

system result:

/Users/homer/mimvp_site/api/header2.php:41:int 0

/Users/homer/mimvp_site/api/header2.php:42:string '' (length=0)

从结果看

1)第一行结果,打印输出命令时,直接在屏幕上打印了 sytem 执行命令的返回结果,没法保存,因此system用于不保存结果的场景

2)第三行结果 $retval 为状态 0 ,表示 cmd 命令执行成功

3)第四行结果 $res 为空字符串 '',表示 cmd 命令执行返回结果的最后一行,其结果为空

 

 

passthru()

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

passthru 和 system 基本是一样的,结果不保存,直接输出在屏幕上,两者仅是返回值不同

1)system 是返回结果的最后一行,类型为 string

2)passthru 不返回结果,类型为 void

说明:

第一个参数, $command 是要执行的命令,例如: "ls -l"

第二个参数,$return_var,用于保存command执行状态,0 - 成功,非零 - 失败

返回值,为空 void

 

示例:

1

2

3

4

5

6

7

8

9

10

// passthru

$retval = null;

$res = null;

 

$cmd = "/usr/bin/curl -k --head 'https://mimvp.com'";

$res = passthru($cmd, $retval);

 

echo " passthru result:";

var_dump($retval);      // 0 (返回的状态, 0 - 成功, 非零 - 失败)

var_dump($res);         // ''

运行结果:

1

2

3

4

5

HTTP/2 200 server: nginx date: Tue, 26 Dec 2017 01:52:11 GMT content-type: text/html; charset=UTF-8 vary: Accept-Encoding vary: Accept-Encoding vary: mimvp-home-bj2 vary: mimvp-homes-bj2

 

passthru result:

/Users/homer/mimvp_site/api/header2.php:48:int 0

/Users/homer/mimvp_site/api/header2.php:49:null

从结果看

1)第一行结果,打印输出命令时,直接在屏幕上打印了 sytem 执行命令的返回结果,没法保存,跟system类似

2)第三行结果 $retval 为状态 0 ,表示 cmd 命令执行成功

3)第四行结果 $res 为空字符串为null,即不返回结果 void

 

 

shell_exec()

原型:string shell_exec ( string $cmd )

shell_exec 与 exec 类似,只是没有返回状态,其状态和cmd执行结果,都以结果返回

1)如果执行cmd成功,则返回执行结果

2)如果执行cmd失败,则返回 NULL

说明:

第一个参数, $command 是要执行的命令,例如: "ls -l"

返回值,为command执行结果,如果失败则返回 NULL

 

示例:

1

2

3

4

5

6

7

8

// shell_exec

$res = null;

 

$cmd = "/usr/bin/curl -k --head 'https://mimvp.com'";

$res = shell_exec($cmd);

 

echo " shell_exec result:";

var_dump($res);         // 返回执行结果,或失败返回NULL

运行结果:

1

2

3

4

5

6

7

8

9

10

11

shell_exec result:

/Users/homer/mimvp_site/api/header2.php:84:string 'HTTP/2 200

server: nginx

date: Tue, 26 Dec 2017 01:52:11 GMT

content-type: text/html; charset=UTF-8

vary: Accept-Encoding

vary: Accept-Encoding

vary: mimvp-home-bj2

vary: mimvp-homes-bj2

 

' (length=198)

从结果看

执行cmd输出结果,以字符串返回给了 $res ,并保留了换行

 

 

popen()

原型:resource popen ( string $command , string $mode )

通过pipe管道执行shell命令,也是一种常见的方式,python也有类似的命令

说明:

第一个参数, $command 是要执行的命令,例如: "ls -l"

第二个参数,$mode 是指定读写、执行等操作类型,如 'r', 'w', 'x'

返回值,是一个资源句柄,可用来具体的操作命令的资源,一般配合 fgets()、fgetss()、fwrite() 使用

 

示例:

1

2

3

4

5

6

// popen

$handle = popen($cmd, 'r');

$res = fread($handle, 8888);

echo " popen result:";

var_dump($res);    

pclose($handle);    // 资源句柄执行完后,一定要记得关闭

运行结果:

1

2

3

4

5

6

7

8

9

10

11

popen result:

/Users/homer/mimvp_site/api/header2.php:90:string 'HTTP/2 200

server: nginx

date: Tue, 26 Dec 2017 02:57:55 GMT

content-type: text/html; charset=UTF-8

vary: Accept-Encoding

vary: Accept-Encoding

vary: mimvp-home-bj2

vary: mimvp-homes-bj2

 

' (length=198)

 

 

PHP 执行命令函数的应用实例

PHP 执行外部命令函数 exec()、system()、passthru()、shell_exec() 不是花瓶,一切皆因需求而生

例如,PHP 前端执行直接从shell获取一些查询结果,充分利用强大的shell命令,如 curl、wget、whois 等

 

PHP 内置函数 get_headers() 用于获取服务器端返回的头信息,如果失败了可以通过 curl --head 来获取

实例代码,封装如下

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

// 获取server返回头信息

function get_response_header($url='https://mimvp.com') {

    $res_headers = array();

     

    try {

        $res_headers = get_headers($url, 1);        // 0 - 不格式化; 1 - 格式化

        if($res_headers == false) { // 返回结果失败

             

            $retval = null;

            $res = null;

            $res_array = array();

            $cmd = sprintf("/usr/bin/curl -k --head '%s'", $url);

            echo ' cmd : ' . $cmd;

             

            // exec

            $res = exec($cmd, $res_array, $retval);

            echo " exec result:";

            var_dump($retval);      // 0 (返回的状态, 0 - 成功, 非零 - 失败)

            var_dump($res);         // ''

            var_dump($res_array);   // 返回结果数组

             

            $idx = 0;

            foreach($res_array as $line) {          // $res_array 转成 $res_headers

                $line = str_replace(":", ":", trim($line));

                 

                if($idx == 0 && $line != "") {      // 处理第一行的状态

                    $res_headers[0] = $line;

                }

                if(strstr($line, ":") != "") {

                    $key = trim(explode(":", $line)[0]);

                    $val = trim(explode(":", $line)[1]);

                    $res_headers[$key] = $val;

                }

                else if($idx >= 2 && $line != "") {

                    $res_headers[$idx] = $line;

                }

                $idx += 1;

            }

        }

    } catch (Exception $e) {

        var_dump($e);

    }

     

    var_dump($res_headers);

    return $res_headers;

}

运行结果

1)正常时,执行 get_headers() ,返回结果如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

/Users/homer/Downloads/myCode/workspace/navi_client/api/header2.php:67:

array (size=6)

  0 => string 'HTTP/1.1 200 OK' (length=15)

  'Server' => string 'nginx' (length=5)

  'Date' => string 'Tue, 26 Dec 2017 02:38:59 GMT' (length=29)

  'Content-Type' => string 'text/html; charset=UTF-8' (length=24)

  'Connection' => string 'close' (length=5)

  'Vary' =>

    array (size=4)

      0 => string 'Accept-Encoding' (length=15)

      1 => string 'Accept-Encoding' (length=15)

      2 => string 'mimvp-home-bj2' (length=14)

      3 => string 'mimvp-homes-bj2' (length=15)

 

2)失败时,执行 curl --head ,返回结果如下:

1

2

3

4

5

6

7

/Users/homer/Downloads/myCode/workspace/navi_client/api/header2.php:67:

array (size=5)

  0 => string 'HTTP/2 200' (length=10)

  'server' => string 'nginx' (length=5)

  'date' => string 'Tue, 26 Dec 2017 02' (length=19)

  'content-type' => string 'text/html; charset=UTF-8' (length=24)

  'vary' => string 'mimvp-homes-bj2' (length=15)

在 shell 执行cmd命令,查看其结果

1

2

3

4

5

6

7

8

9

10

$ /usr/bin/curl -k --head 'https://mimvp.com'

HTTP/1.1 200 OK

Server: nginx

Date: Tue, 26 Dec 2017 02:45:52 GMT

Content-Type: text/html; charset=UTF-8

Connection: keep-alive

Vary: Accept-Encoding

Vary: Accept-Encoding

Vary: mimvp-home-bj2

Vary: mimvp-homes-bj2

可见,curl --head 基本补充了 get_headers 执行失败时获取服务器端头信息的功能

还有一点瑕疵就是 Vary 变量数组处理的不完美,完整代码量大,在此不给出了,请自行判断实现之

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3