首先,PHP有多种方式运行shell脚本:system()输出shell执行结果并返回值为最后一行结果, exec()不输出结果返回最后一行shell结果,shell_exec()不输出结果返回所有结果,passthru()将命令结果输出到标准输入输出设备上。本文中采用shell_exec()函数,要执行的脚本为read_msr.sh,读取msr寄存器,需要root权限。
php页面的内容为<?php echo shell_exec("sudo sh read_msr.sh"); ?>
通过浏览器访问,并没有返回内容。查看tomcat的日志文件,但并没有错误记录。于是在命令行使用php命令解析此PHP页面:在root用户时,可以正确返回shell结果;切换到tomcat用户(浏览器访问时为tomcat用户,可以在/etc/passwd修改允许tomcat登陆),发现要求输入密码。因此,要允许tomcat不需要密码执行sudo:vim /etc/sudoers 添加一行tomcat: ALL=(ALL) PASSWD:(ALL),使用x!保存退出(sudoers为只读文件) 【参考文献1,在提问者对回答这的回复中】。
到此,满怀希望的再次使用浏览器访问,可惜依旧白纸一张,郁闷!查看日志还是没有什么信息,又捣鼓了一阵子还是没有头绪。
后来,看到将错误信息重定向输出的一篇博客【之后没有找到博客链接,就不引了,博主勿怪...】,就自己试了一下,shell_exec("sudo sh read_msr.sh 2>&1"),果然出现了一条错误信息“sudo: sorry, you must have a tty to run sudo”。这是因为sudo命令默认要求在tty终端运行,解决方法就是将sudoers文件中的一条Default requiretty注释掉【参考文献2,3】。
至此浏览器访问php页面,root权限的shell就可以运行了。
参考资料:
1. php exec() command permission denied, http://stackoverflow.com/questions/10236091/php-exec-command-permission-denied
2. sudo: sorry, you must have a tty to run sudo, http://www.linuxidc.com/Linux/2012-11/75153.htm
3. 如何解决 sudo: sorry, you must have a tty to run sudo,http://zpz.name/2130/