2013-01-02 92 views
5

我有一个系统脚本,它运行并将“ps aux | grep工具”的结果传输到文本文件并传递文本文件,以便Web服务可以读取文件并在我的Web应用程序中显示结果。php来解析ps aux | grep ...结果

这里是原始结果的一个例子:

user  12052 0.2 0.1 137184 13056 ?  Ss 10:00 0:00 php /home/user/public_html/utilities/runProcFile.php cust1 cron 
user  12054 0.2 0.1 137184 13064 ?  Ss 10:00 0:00 php /home/user/public_html/utilities/runProcFile.php cust3 cron 
user  12055 0.6 0.1 137844 14220 ?  Ss 10:00 0:00 php /home/user/public_html/utilities/runProcFile.php cust4 cron 
user  12057 0.2 0.1 137184 13052 ?  Ss 10:00 0:00 php /home/user/public_html/utilities/runProcFile.php cust89 cron 
user  12058 0.2 0.1 137184 13052 ?  Ss 10:00 0:00 php /home/user/public_html/utilities/runProcFile.php cust435 cron 
user  12059 0.3 0.1 135112 13000 ?  Ss 10:00 0:00 php /home/user/public_html/utilities/runProcFile.php cust16 cron 
root  12068 0.0 0.0 106088 1164 pts/1 S+ 10:00 0:00 sh -c ps aux | grep utilities > /home/user/public_html/logs/dashboard/currentlyPosting.txt 
root  12070 0.0 0.0 103240 828 pts/1 R+ 10:00 0:00 grep utilities 

至于我的PHP脚本解析这个文本文件,我只需要提取以下(只是一个例子):

cust1 
cust3 
cust4 
cust89 
cust435 
cust16 

我有尝试了许多不同的笨拙方式,似乎没有什么效果。我在下面列出的方法是有效的,但有时也会因为一行中“空格”的数量在更改时爆炸而占用垃圾。

public function showProcesses() { 
    $lines = file(DIR_LOGGER_ROOT . "dashboard/currentlyPosting.txt"); 
    $results = array(); 
    $i = 0; 
    foreach($lines as $line) { 
     if (preg_match("/php/i", $line)) { 
      $userProcess = explode(" ", $line); 
      if($userProcess[29] != "0:00" && strlen($userProcess[29]) < 20) { 
       $results[$i] = $userProcess[29]; 
       $i++; 
      } 
     } 
    } 
    return $results; 
} 

难道你们中的一些人会为此发布优雅的解决方案吗?我正在努力学习更好的做事方式,并希望得到指导。

+0

如果你正在写一个命令行应用程序要做到这一点,我建议使用更适合字符串处理和正则表达式如Perl语言。你甚至可能甚至可以在CPAN上找到一些东西直接访问进程表,例如http://search.cpan.org/dist/Proc-ProcessTable/ –

+0

,数据将从系统脚本中收集并写入文本文件。它使我的Web应用程序可访问文本文件,而无需使用我的Web应用程序中的exec和root。但解析结果是为了Web应用程序本身,所以PHP是有道理的。 –

回答

0

我会用preg_match()。我为我的许多系统管理脚本做了类似的事情。下面是一个例子:

$test = "user  12052 0.2 0.1 137184 13056 ?  Ss 10:00 0:00 php /home/user/public_html/utilities/runProcFile.php cust1 cron 
user  12054 0.2 0.1 137184 13064 ?  Ss 10:00 0:00 php /home/user/public_html/utilities/runProcFile.php cust3 cron 
user  12055 0.6 0.1 137844 14220 ?  Ss 10:00 0:00 php /home/user/public_html/utilities/runProcFile.php cust4 cron 
user  12057 0.2 0.1 137184 13052 ?  Ss 10:00 0:00 php /home/user/public_html/utilities/runProcFile.php cust89 cron 
user  12058 0.2 0.1 137184 13052 ?  Ss 10:00 0:00 php /home/user/public_html/utilities/runProcFile.php cust435 cron 
user  12059 0.3 0.1 135112 13000 ?  Ss 10:00 0:00 php /home/user/public_html/utilities/runProcFile.php cust16 cron 
root  12068 0.0 0.0 106088 1164 pts/1 S+ 10:00 0:00 sh -c ps aux | grep utilities > /home/user/public_html/logs/dashboard/currentlyPosting.txt 
root  12070 0.0 0.0 103240 828 pts/1 R+ 10:00 0:00 grep utilities"; 

$lines = explode("\n", $test); 

foreach($lines as $line){ 
     if(preg_match("/.php[\s+](cust[\d]+)[\s+]cron/i", $line, $matches)){ 
       print_r($matches); 
     } 

} 

上面打印:

Array 
(
    [0] => .php cust1 cron 
    [1] => cust1 
) 
Array 
(
    [0] => .php cust3 cron 
    [1] => cust3 
) 
Array 
(
    [0] => .php cust4 cron 
    [1] => cust4 
) 
Array 
(
    [0] => .php cust89 cron 
    [1] => cust89 
) 
Array 
(
    [0] => .php cust435 cron 
    [1] => cust435 
) 
Array 
(
    [0] => .php cust16 cron 
    [1] => cust16 
) 

可以设置$test从EXEC等于输出。您正在查找的值将位于foreach下的if语句中。 $matches[1]将具有custx值。

1

您可以使用preg_split而不是explode并拆分为[ ]+(一个或多个空格)。但我认为,在这种情况下,你可以用preg_match_allcapturing去:

preg_match_all('/[ ]php[ ]+\S+[ ]+(\S+)/', $input, $matches); 
$result = $matches[1]; 

的格局空间,php,更多的空间,非空间(路径)的字符串,更多的空间相匹配,然后捕获下一串非空格。第一个空间主要是为了确保你不匹配php作为用户名的一部分,但实际上只是作为一个命令。

捕获的替代方法是PCRE的“保留”功能。如果您在模式中使用\K,之前的一切是在比赛中放弃:

preg_match_all('/[ ]php[ ]+\S+[ ]+\K\S+/', $input, $matches); 
$result = $matches[0]; 
0

如果在你的行间距值之间的数量是可变的,你可以使用preg_split

你只会有改变:

$userProcess = explode(" ", $line); 

到:

$userProcess = preg_split("#\s+#", $line); 

\s+将匹配一个或多个空格,制表符或其他空格字符。

然后你就可以得到倒数第二项:

$txt = $userProcess[count($userProcess) - 2];