php在cli命令行执行exec函数中的top命令正常,浏览器访问无输出

问题:

monitor.php

<?php

var_dump(exec('top -n 1 |grep Cpu 2>err.txt ',$r, $r2));
var_dump($r); 
var_dump($r2);

?>

写了这样一个php,在命令行使用php monitor.php成功输出结果。但是在浏览器访问没有输出,也不报错。


不报错原因:

使用了管道|,则不会报出错误。去掉管道,发现错误为TERM environment variable not set.

解决办法:

搜索该错误,发现php.net提供了一种方法如下:

Remember that some shell commands in *NIX needs you to set a TERM enviroment. For example:
<?php
exec
('top n 1 b i'$top$error );
echo 
nl2br(implode("\n",$top));
if (
$error){
    
exec('/usr/bin/top n 1 b 2>&1'$error );
    echo 
"Error: ";
    exit(
$error[0]);
}
?> 
This will echo "Error: TERM enviroment variable not set. " To fix it, add  TERM=xterm (Or some other terminal) to the exec-statement, like this

<?php
exec
('TERM=xterm /usr/bin/top n 1 b i'$top$error );
echo 
nl2br(implode("\n",$top));
if (
$error){
    
exec('TERM=xterm /usr/bin/top n 1 b 2>&1'$error );
    echo 
"Error: ";
    exit(
$error[0]);
}
?>

但是为什么命令行执行可以呢?猜想应该跟环境变量有关系吧?shell下面执行php可以看到所有的变量,但是浏览器访问的话只能使用环境变量。

环境变量取值:环境变量TERM设置为终端类型

终端是一个很重要的外设,用过终端设备的人都知道如果设备类型不对就会有乱字符,也可用仿真终端软件如netterm试验一下,linux的终端信息放在   /usr/share/terminfo下,在这个目录的子目录v下就有许多的如vt100,vt102,vt200等,你看一下就知道了。

我的/usr/share/terminfo/v目录下有个vwmterm文件,我尝试了一下

var_dump(exec('TERM=vwmterm top -n 1 i 2>err.txt',$r, $r2));
var_dump($r); 
var_dump($r2);

这次又报错了,错误信息为:top: failed tty get

搜索该错误,发现:

通过其他程序或脚本在非交互式模式下调用top命令,经常会出现:
   top: failed tty get 错误
解决办法:加个-b 选项皆可
-b : Batch mode operation
   Starts  top  in  <A1><AF>Batch mode<A1><AF>, which could be useful for sending output from top to other programs or to a file.  In this mode, top will not accept input and runs until the iterations limit you<A1><AF>ve set with the <A1><AF>-n<A1><AF> command-line option or until killed.
例如执行:top -bn 1

因此我把原来代码改为如下就好了:

var_dump(exec('top -n 1 b i 2>err.txt',$r, $r2));
var_dump($r); 
var_dump($r2);

这样就可以正常输出了,因此对此类问题的解决方式为,输出错误,根据错误信息更改代码解决错误即可。


总结:

1)用php程序监控服务器运行状态,包括cpu使用率、可用内存大小、已使用内存大小、硬盘分区使用情况、mysql连接数
2)查询指定进程名的进程数
反馈:

核心知识点1、php调用系统命令内置函数:主要是exec、shell_exec、system。它们的主要区别是返回参数的不同。另外, php5.4之前版本需要在php.ini中设置关闭安全模式。 5.4之后的版本不在支持安全模式。 其他php调用系统命令的函数还有: passthru,escapeshellcmd等。
遇到的问题:包含exec命令的php文件通过命令行可以被php执行,获得返回值,而通过网络访问该php文件则无任何返回。
解决过程:首先查看php.ini文件,以及网络访问phpinfo信息,发现disable_functions参数中写入了exec等函数。去除该参数后,对大部分命令都可以正常返回信息了。但是,为何命令行本来就可以正常执行呢?通过命令行打印phpinfo信息,发现php命令行模式的配置文件在另外一处,也就是有两个php.ini文件,分别给cli何网络访问用的。然而,发现top命令在cli下可以正常返回,在网络访问时无返回值。于是,在命令中加入报错命令,竟然也没用返回错误信息。后来发现, 无错误信息的原因是命令中包含了管道命令,而有管道命令时错误信息不会写入err.html文件。去除管道命令,报错信息主要有两种,一种是term变量未写入环境变量,一种是top命令需要加上-b选项才可以通过网络执行。还有其他命令有时也会无法返回结果,解决方法类似,输出错误信息,依据信息排查即可。

核心知识点2、shell常用命令。man命令、info命令、ls、cp、mv、rm、cd、pwd、mkdir、rmdir、file、cat、ln、whereis、whatis、find、grep、tar、./configure、make、make install、chmod。系统命令: top、htop、whoami、cu、uptime、date、ping、ifconfig、ps、lspci、lsusb、env等。

其他知识点:正则表达式、字符串截取、js定时、ajax。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值