Linux下php调用命令行的小研究

OS:RedHat Linux 5

最近在弄php。和J2EE那一套比较起来,个人感觉php要轻便适手许多。

单配置而言,Linux环境下需要apache以及php,当前最新版本的为5.3.6。但是建议使用5.2或者更早的,新版本目前还不算稳定,某些方法的使用可能会有点版本兼容问题,譬如各种时间函数,还有部分字符串处理如split()等。

相对于java开发环境,简单得操蛋。

在windows环境下有很多集成php开发工具,wamp是目前所见最易上手的。它集成了php、apache以及MySql,统统一键搞定。

好了,正题。

php调用命令行的常用方法包括:exec,system,shell_exec,passthru()。

===================来自百度的分界线================

system() 输出并返回最后一行shell结果。

exec() 不输出结果,返回最后一行shell结果,所有结果可以保存到一个返回的数组里面。

passthru() 只调用命令,把命令的运行结果原样地直接输出到标准输出设备上。

shell_exec() 命令行实际上仅是反撇号 (`) 操作符的变体。如果您编写过 shell 或 Perl 脚本,您就知道可以在反撇号操作符内部捕捉其他命令的输出。

==============================================

在这里最好用的莫过于shell_exec()。

上面说了,那应该能想到,shell_exec()有最直接的引用返回方法,如下:

CODE:

$result=shell_exec("ls");

print $result;

打印用户目录(因为默认的执行目录就是用户目录“~”)下的所有文件、目录名。

我们可以简化一下,如下:

CODE:

$result=`ls`;

print $result;

print `ls`;

注意,“ ` ”这个符号是反撇号,在大键盘数字键“1”的左侧的那个。

两个print都会输出同样的结果。

好的东西总是有缺陷的,不然我会说它是完美的东西,shell_exec()不能返回错误。

而system就能做到。如下:

CODE:

system("ls",$sto);

print $sto;

如果太过于熟悉java开发,这里的$sto可以视为java的传引用。$sto的返回值是为整数,0为命令通过,不为0则是错误号码返回。目前我仅仅关注了权限,可知返回值1表示权限问题: Permission denied。

system的使用也会产生问题,如下:

CODE:

print system("ls",$sto);

该行语句会将用户目录下的所有文件、目录名打印两遍。

这是因为system本身的功能就是“字符串转化为输入流,执行,输出流转化字符串,打印”,你可以把system视作exec和print的合体。

从这里我们知道,集合的不一定是好的,缺乏灵活性。

所以,这种情况下还是建议使用exec,使用方法同system。

 

这是一些基本的使用,现在来总结下开发中遇到的问题。

1、php 5.3.6的命令行格式。你可能会需要使用sudo touch newfile.txt,为了适用不同环境,你可能会把它整成 /usr/bin/sudo /bin/touch newfile.txt。

那好,你完了。它不会被执行。

奇怪的事情发生了,假如,默认的conf可以识别touch,而不需加入绝对路径,php 5.3.6就不允许你在工具引用命令上加入绝对路径。这点很奇怪,在使用php 5.2的时候并没有出现这种问题。

你需要写成:/usr/bin/sudo touch newfile.txt

同样的,假如,你要整一个逻辑单元,使用sudo lvm lvcreate命令

第二个lvm不需要,也请不要使用,php 5.3.6在调用第二层工具的时候也会出现同样的问题,目前本人还没研究出原因。

sudo lvcreate已经够用了。

2、php 5.3.6对split()做了改写,如果你想实现分割字符串的功能,请尽量使用explode()。

3、关于sudo的配置,这个是通用问题。只要涉及到页面调用命令行,就一定会有权限问题。

你敢给界面用户命令行root权限么?那,还是老老实实配置sudo吧。

visudo是个很好用的工具,它会检测你对/etc/sudoers的改写,当不能正确解析时候,visudo会报告问题。当然如果你非要坚持vi /etc/sudoers,谁也不能阻止你发疯,是不是?

#visudo

加入下面这行:

myusr ALL=(ALL)NOPASSWD:ALL

myusr表示你要赋予sudo权限的用户名,第一个ALL表示,给所有访问端口同样的权限,它的选项可以有LOCAL,NETWORK等。

之后的NOPASSWD表示,在使用sudo时候不需要密码验证。括号里的ALL,由于本人比较懒,还没研究……

冒号后面还有个ALL,这是说,你要赋予sudo权限的命令集。ALL指代全部命令,你可以在后面添加单一的命令,或者整个命令文件夹。

注意:有时候你会发现,即时使用了sudo,在页面调用命令时还是会报出权限错误,这很可能是因为tty验证。注意某一行(Defaults    requiretty),用#注释掉,就可以了。

上一篇:基于HttpClient的HttpUtils(后台访问URL)


下一篇:React 实践心得:key 属性的原理和用法