在PHP中解析Linux命令'who'的输出

时间:2010-01-30 22:47:42

标签: php linux bash parsing command-line

我尝试解析当前通过SSH连接到服务器的用户列表,但结果非常不规律,所以我不得不这样做:

$users = shell_exec('who');
echo "<pre>$users</pre>";

在让PHP乱七八糟之前,是否有更好的方法在命令行中解析who的输出?我希望它包含一个数组,其中包含用户名(下面的第一列),它们连接的终端(第二列),它们连接的日期和时间(第三列),以及它们连接的IP(括号内)。我猜我应该使用preg_split来分割数据,但有时用户名长度,终端名称等似乎是不规则的。

who的一些示例输出):

alex     tty7         2010-01-23 17:04 (:0)
alex     pts/0        2010-01-30 17:43 (192.168.1.102)
root     pts/1        2010-01-30 17:45 (192.168.1.102)

3 个答案:

答案 0 :(得分:4)

explode()换行符(\n)会为您提供一个数组,每行包含一个项目,当您遍历数组并使用preg_split("/\s+/", $sValue, 3)时,它应该为您提供一个新的将每列作为项目的数组。然后你需要拆分日期和地址。

完整的代码将是这样的:

<?php
$sTempUsers = shell_exec('who');
$aTempUsers = explode("\n", $sTempUsers);

$aUsers = array();
foreach($aTempUsers AS $sUser)
{
    $aTempUser = preg_split("/\s+/", $sUser, 3); // username | terminal | date addr
    preg_match("/^(.+)\s\((.+)\)$/", $aTempUser[2], $aDateAndAddr); // full match | date | addr

    $aUsers[] = array(
        $aTempUser[0], 
        $aTempUser[1], 
        $aDateAndAddr[1], 
        $aDateAndAddr[2]
    ); // username | terminal | date | addr
}
?>

您可以在$aUsers找到结果。

答案 1 :(得分:0)

preg_split只需匹配数据之间的空间,而不是数据本身:

$who = shell_exec('who');
$users = array();
foreach(split("\n", $who) as $user) {
  $users[] = preg_split("/\s{2,}/", $user); //Match 2 or more whitespace chars
}

答案 2 :(得分:0)

$who = shell_exec('who');
$s = split("\n",$who);
$func = function($value) { return preg_split("/\s{2,}/",$value ); };
print_r(array_map($func, $s));