2013-01-02 14 views
5

Ho uno script di sistema che esegue e convoglia i risultati di "ps aux | grep utilities" in un file di testo e rimuove il file di testo in modo che il servizio Web possa leggere il file e visualizzare i risultati nella mia app web.php per analizzare ps aux | grep ... results

Ecco un esempio dei risultati grezzi:

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 

Come il mio script php analizza questo file di testo, ho solo bisogno di estrarre i seguenti (solo un esempio):

cust1 
cust3 
cust4 
cust89 
cust435 
cust16 

ho provato un certo numero di modi diversi maldestri e niente sembra funzionare bene. Il modo in cui ho elencato di seguito funziona, ma a volte afferra anche i rifiuti perché il numero di "spazi" in una linea esplode in base alle modifiche.

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

Alcuni di voi potrebbero postare soluzioni eleganti per questo? Sto cercando di imparare modi migliori di fare le cose e apprezzerei la guida.

+0

Se state scrivendo un'applicazione a riga di comando per fare questo, io suggerisco di usare un linguaggio più adatto per la gestione delle stringhe e le espressioni regolari come il Perl. Probabilmente potresti anche trovare qualcosa su CPAN per accedere direttamente alla tabella dei processi, come http://search.cpan.org/dist/Proc-ProcessTable/ –

+0

i dati vengono raccolti e scritti nel file di testo da uno script di sistema. rende accessibile il file di testo alla mia app Web senza utilizzare exec e root dalla mia app Web. ma analizzare i risultati è per l'app Web stessa, quindi php ha senso. –

risposta

0

Vorrei utilizzare preg_match(). Faccio qualcosa di simile per molti dei miei script di gestione del sistema. Ecco un esempio:

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

} 

Le stampe di cui sopra:

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 
) 

È possibile impostare $test per eguagliare l'output di exec. i valori che stai cercando sono nell'istruzione if sotto lo foreach. $matches[1] avrà il valore di custx.

1

È possibile utilizzare preg_split anziché explode e dividere su [ ]+ (uno o più spazi). Ma credo che in questo caso si potrebbe andare con preg_match_all e capturing:

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

il modello corrisponde uno spazio, php, più spazi, una serie di non-spazi (il percorso), più spazi, e quindi cattura i stringa successiva di non spazi. Il primo spazio consiste principalmente nel garantire che non si corrisponda a php come parte di un nome utente, ma solo come comando.

Un'alternativa all'acquisizione è la funzione di "mantenimento" di PCRE. Se si utilizza \K nel modello, tutto prima di essere scartato nel match:

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

Se il numero di spazi in linea tra i valori è variabile, è possibile utilizzare preg_split

Si potrebbe solo avere di cambiare:

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

a:

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

\s+ corrisponderà a uno o più spazi, tabulazioni o altri caratteri spazi bianchi.

Poi si può ottenere l'oggetto penultima con:

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