2,137   Linux PHP

一,背景

1,服务器日志文件比较大,一般直接在Linux上使用grep查询;

2,有时需要把某些重要的日志导出来,利用程序进行分析;

这涉及到PHP程序执行shell命令的问题

 

二,PHP执行shell命令

exec()函数会执行$command的shell命令,然后把结果一行行地放入$array数组中;另外还有一个shell_exec()函数,它则会把结果直接赋给字符串;

示例代码:

$commamd='ls -rhtl';

echo 'exec',"\n";
$output = array();
exec($commamd,$output);
var_dump($output);

echo 'shell_exec',"\n";
$string=shell_exec($commamd);
var_dump($string);

 

运行结果:

 

chenyunhui@ubuntu:/mnt/hgfs/ShareFolder/web/test$ ls -rhtl
total 8.5K
-rwxrwxrwx 1 root root 929 Apr 30 11:35 test.js
-rwxrwxrwx 1 root root  39 Apr 30 12:49 test.txt
-rwxrwxrwx 1 root root 873 Apr 30 13:07 test.php
chenyunhui@ubuntu:/mnt/hgfs/ShareFolder/web/test$ php test.php
exec
array(4) {
  [0]=>
  string(10) "total 8.5K"
  [1]=>
  string(47) "-rwxrwxrwx 1 root root 929 Apr 30 11:35 test.js"
  [2]=>
  string(48) "-rwxrwxrwx 1 root root  39 Apr 30 12:49 test.txt"
  [3]=>
  string(48) "-rwxrwxrwx 1 root root 873 Apr 30 13:07 test.php"
}
shell_exec
string(157) "total 8.5K
-rwxrwxrwx 1 root root 929 Apr 30 11:35 test.js
-rwxrwxrwx 1 root root  39 Apr 30 12:49 test.txt
-rwxrwxrwx 1 root root 873 Apr 30 13:07 test.php
"


 

 

三,PHP执行grep命令定位字符串

 

想把特定字符串搜索出来并做后续处理,先定位字符串

示例代码:

 

// 获取输入搜索的字符串
$key=$argv[1];
// grep 命令,-n显示行数,搜索$key,文件名为test.txt
$commamd='grep -n '.$key.' test.txt';

// 执行grep命令,输出搜索内容到$output
$output = array();
exec($commamd,$output);

if($output){
	$key_arr = array();
	// 循环读取,获取行数$line和列数$col
	foreach($output as $val){
		// grep -n 输出行数,用分号 : 隔开,后面是行内容
		list($line,$str) = explode(':',$val);

		// 每一行$str中可能包含多个搜索关键字$key
		// 多次调用getCols找出所有$key的列数$col
		$key_arr = getCols($key_arr,$line,0,$str,$key);
		
	}
}

// 找出一行字符串中所有$key的列数
function getCols($key_arr,$line,$start,$str,$key){
	// 获取第一个$key出现的位置
	$rtn=strpos($str,$key);
	// 如果没有则结束
	if($rtn===false){
		return $key_arr;
	}
	// strpos是从0开始计算的,所以加1
	$col=$rtn+1;
	// 如果这是第二个以上的$key,则需要把前面的列数加上
	$n_col=$start+$col;
	// 把$key出现的行数$line和列数$col放入数组
	array_push($key_arr, array($line,$n_col));

	// 截取$key后面的字符串
	$n_str=substr($str,$col);
	// 继续搜索下一个$key出现的位置
	return getCols($key_arr,$line,$n_col,$n_str,$key);

}


// 打印test.txt的所有内容
$commamd = 'cat test.txt';
$string = shell_exec($commamd);

echo 'test.txt content';
echo "\n";
echo "\n";
echo $string;
echo "\n";

echo "\n";
echo 'search:'.$key;
echo "\n";
if($key_arr){
	foreach($key_arr as $val){
		echo 'line:'.$val[0].',col:'.$val[1];
		echo "\n";
	}
}

 

 

运行结果:

 

chenyunhui@ubuntu:/mnt/hgfs/ShareFolder/web/test$ php test.php a
test.txt content

1234567
abacadefghijklnm
123
asdfasf

search:a
line:2,col:1
line:2,col:3
line:2,col:5
line:4,col:1
line:4,col:5

 

由结果可知,已经可有搜索出现特定字符,即使一行中有多个特定字符,也定位到了;
现在可以从Linux的大日志文件中,通过PHP程序获取你想要的字符串啦;




Leave a Reply

Your email address will not be published. Required fields are marked *