logo头像
Snippet 博客主题

PHP在Linux下运行Shell命令

本文于 2229 天之前发表,文中内容可能已经过时。

原本在本机开发PHP的时候,Shell调用一切正常。上线的时候才反应到线上的服务器对权限做了严格的控制,一顿折腾之后梳理出在严格权限控制的Linux上如何通过Nginx/Apache 以Web的方式调用Shell命令,比如调用java编译或者执行java程序。

Web服务器使用www用户启动。分为两种情况:一种是命令是通过root安装的,并不能直接把权限直接赋给www用户,比如/usr/local/nginx/sbin/nginx;一种是www用户对要执行的命令有绝对的权限,但是由于缺少某些环境变量,执行的程序如果用到了这些变量就得提前再次设定环境变量。

先说第一种,其实php.ini里面已经定义了不可以调用的命令,默认情况下exec, system之类都不能执行。首先要去php.ini里面把

disable_functions=

这一项里面定义的那些调用Shell脚本的函数移出列表,然后重启Nginx的PHP-PFM或者Apache。可以测试一下

<?php echo exec(“pwd”); ?>

正常情况下应该就可以看到当前的路径信息了。但是要想执行一些root才能执行的命令,比如重新加载Nginx配置文件,还需要一些额外的操作,这里参考http://bbs.chinaunix.net/thread-3693263-1-1.html

1、设置 sudo 配置文件 可写权限

chmod u+w /etc/sudoers

2、增加 www 用户的 nginx 脚本管理权限

www ALL=(root) NOPASSWD: /etc/init.d/nginx

3、关闭 【强制控制台登录】执行

【非常重要】,注释该行 我的问题就出在这里,开启了这个选项之后。在PHP中怎么调用,都没有执行结果

#Defaults requiretty

4、还原 sudo 配置权限 440

【非常重要】,如果不还原权限。在PHP中怎么调用,都没有执行结果。

chmod u-w /etc/sudoers

5、调用php

$result2 = exec(“/usr/bin/sudo /etc/init.d/nginx stop”,$result);

var_dump($result);

var_dump($result2);

再看看如果调用Java编译并执行。www用户拥有对/work/java目录的执行权限。直接上代码:

Java的,文件名”TestJava.java”

public class TestJava{

public static void main(String[] args) {

System.out.println(“Hello World!”);

}

}

PHP的,文件名”test.php”

<?php

function del_file($file){

if(file_exists($file) && unlink($file) ){

echo “del “.$file.”
\r\n”;

}

}

function execute($exe){

echo $exe.”
\r\n”;

$r=exec($exe, $res);

var_dump($res);

echo “
———————-
\r\n”;

var_dump($r);

echo “
———————-
\r\n”;

}

$target_file = “TestJava.class”;

$output_file = “output.txt”;

$src=”/work/web/services.adsage.com/deploy/monitor/test/TestJava.java”;

$bin=”TestJava”;

$jcommon = “export JAVA_HOME=/work/java\nexport JRE_HOME=$JAVA_HOME/jre\nexport PATH=$JAVA_HOME/bin:$PATH\n/work/java/bin/”;

$javac=$jcommon.”javac “.$src;

$javab=$jcommon.”java “.$bin.” >> “.$output_file;

del_file($target_file);

del_file($output_file);

execute($javac);

execute($javab);

echo “final:
\r\n”;

$output=file_get_contents($output_file);

echo $output;

?>

通过Web浏览结果:

del TestJava.class

del output.txt

export JAVA_HOME=/work/java export JRE_HOME=/jre export PATH=/bin: /work/java/bin/javac /work/web/services.adsage.com/deploy/monitor/test/TestJava.java

array(0) { }

———————-

string(0) “”

———————-

export JAVA_HOME=/work/java export JRE_HOME=/jre export PATH=/bin: /work/java/bin/java TestJava >> output.txt

array(0) { }

———————-

string(0) “”

———————-

final:

Hello World!