Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

php to parse ps aux | grep ... results

Tags:

regex

php

I have a system script that runs and pipes the results of "ps aux | grep utilities" to a textfile and chowns the textfile so the web service can read the file and display the results in my web app.

Here is an example of the raw results:

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

As my php script parses this textfile, I only need to extract the following (just an example):

cust1
cust3
cust4
cust89
cust435
cust16

I have tried a number of different clumsy ways and nothing seems to work well. The way I have listed below works, but sometimes grabs garbage too because the number of "spaces" in a line to explode on changes.

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;
}

Could a few of you post elegant solutions for this please? I am trying to learn better ways of doing things and would appreciate the guidance.

like image 482
Stephen Funk Avatar asked Nov 13 '22 14:11

Stephen Funk


1 Answers

You could use preg_split instead of explode and split on [ ]+ (one or more spaces). But I think in this case you could go with preg_match_all and capturing:

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

The pattern matches a space, php, more spaces, a string of non-spaces (the path), more spaces, and then captures the next string of non-spaces. The first space is mostly to ensure that you don't match php as part of a user name but really only as a command.

An alternative to capturing is the "keep" feature of PCRE. If you use \K in the pattern, everything before it is discarded in the match:

preg_match_all('/[ ]php[ ]+\S+[ ]+\K\S+/', $input, $matches);
$result = $matches[0];
like image 104
Martin Ender Avatar answered Nov 15 '22 06:11

Martin Ender