【问题标题】:PHP : Preserve the output formatting of System()PHP:保留 System() 的输出格式
【发布时间】:2012-06-20 20:10:43
【问题描述】:

如何获得控制台上显示的命令输出?

<?php
ob_start();
system('faxstat -s' , $retval);
$last_line = ob_get_contents();
ob_end_clean();
preg_match('/^32.+\s{9}(.*)/m', $last_line, $job_id);
?>

在控制台中,输出如下:

JID  Pri S  Owner Number       Pages Dials     TTS Status
36   127 R www-da 0xxxxxxxx     0:1   0:12         
32   127 R www-da 0xxxxxxxx     0:1   0:12         
35   127 R www-da 0xxxxxxxx     0:1   0:12         

但在 PHP 中,$last_line 的回声是这样的:

JID Pri S Owner Number Pages Dials TTS Status 36 127 R www-da 0xxxxxxxx 0:1 0:12 32 127 R www-da 0xxxxxxxx
0:1 0:12 35 127 R www-da 0xxxxxxxx 0:1 0:12

注意:我不想打印输出,所以不需要&lt;pre&gt; 标签。我想preg_match它。因为它丢失了格式,所以我的正则表达式没用。

【问题讨论】:

  • 如果你把它PRE出来或者只是看一下html页面的源代码,它是不是格式不正确?它应该在 HTML 输出中不保留正常的空格,但我会惊讶于它们在内存中丢失了......
  • @MathieuDumoulin 如果我使用&lt;Pre&gt; 进行打印,它看起来确实如此。但它并不完全相同,我的目标不是打印输出。
  • 我无法在此处重现“格式丢失”。我只能假设您正在浏览器中查看它删除格式。
  • 是的,只返回最后一行。 php.net/manual/en/function.exec.php 使用 exec(command,$output); $ouput 将变成一个用行填充的数组
  • 我会使用preg_split('/\s+/', $line) 来分割空白字符。然后你可以按数字引用每一列。

标签: php formatting system


【解决方案1】:

您需要将exec 与通过引用传递给它的变量一起使用以捕获您的输出线。

$lastLine = exec('df -h',$output);

exec 只返回它遇到的最后一行作为它的返回值,你会发现在你的 $output 参数中执行的命令 exec 的完整输出(你提供的变量by reference exec() 转换为一个数组和已满,另见PHP: References Explained)

例如

<?php
$lastLine = exec('df -h',$output);

print "\n$lastLine\n";
print_r($output);

将打印

none                  990M     0  990M   0% /var/lock

Array
(
    [0] => Filesystem            Size  Used Avail Use% Mounted on
    [1] => /dev/sda1             145G  140G  5.8G  97% /
    [2] => none                  981M  668K  980M   1% /dev
    [3] => none                  990M  3.4M  986M   1% /dev/shm
    [4] => none                  990M  240K  989M   1% /var/run
    [5] => none                  990M     0  990M   0% /var/lock
)

所以你可以看到 $lastLine 确实是命令打印的最后一行

我不明白为什么 shell_exec 或反引号对你不起作用,对不起。

现在是你的解析模式:

<?php

// was stil using your posted 'wrong output'
$output = "JID Pri S Owner Number Pages Dials TTS Status 36 127 R www-da 0xxxxxxxx 0:1 0:12 32 127 R www-da 0xxxxxxxx 
0:1 0:12 35 127 R www-da 0xxxxxxxx 0:1 0:12";

// we just strip the header out
$header = "JID Pri S Owner Number Pages Dials TTS Status ";

$headerless = str_replace($header,'',$output);

$pattern = '/([0-9]+)\s+([0-9]+)\s+([A-Z]+)\s+([^\s]+)\s+([^\s]+)\s+([0-9:]+)\s+([0-9:]+)/m'; // m to let it traverse multi-line

/*
  we match on 0-9 whitespace 0-9 WS A-Z 'Anything not WS' WS ANWS WS 0-9:0-9 WS 0-9:0-9
*/
preg_match_all($pattern,$headerless,$matches);
print_r($matches);

这将为您提供所有单独的元素。显然,当您使用 exec 将其返回到数组中时,您不需要剥离标题以及所有这些,但我认为该模式应该可以正常工作。

【讨论】:

  • 非常感谢。解析一个巨大的字符串是一个非常好的主意。
【解决方案2】:

如果您不想输出任何内容,也可以使用exec()。但是$last_line 将只包含命令打印的实际最后一行。如果要处理整个输出,可以将其重定向到第二个参数为exec() 的数组。

【讨论】:

    【解决方案3】:

    使用反引号运算符 (`) 应保留输出格式。

    $lastline = `ls`;
    

    【讨论】:

    • 这是一回事。它不保存任何东西。另外,我与 HTML 无关。我只想 preg_match 字符串并在 PHP 端完成我的工作。
    • system() 只返回最后一行,xperator 想要捕获所有输出
    • @HaraldBrinkhof 不是真的。调用systemexec 或使用反引号运算符将给出几乎相同的结果。我无法重现他的问题。
    • system 的返回值只返回最后一行,如php.net/manual/en/function.system.phpShell_exec 中所述(或反引号将全部返回,取消投票)
    • backtick 与 shell_exec 相同,但在服务器上激活 safe_mode 时它不起作用,这可能会给您带来困扰。
    【解决方案4】:

    如果没有看到您用于匹配的正则表达式,很难说。我的猜测是您正在尝试匹配不在此转换字符串中的非打印字符。尝试在 \s 上进行匹配,这将查找多种类型的空白字符。

    【讨论】:

    • 你想隔离什么?
    • 我猜你想从只有 32 的行中得到一个值。你有一个对 \s{9} 的引用,这意味着正好 9 个空白字符。您的示例系统输出中没有它。我只将 5 算作输出中最大的空白。
    • 看看这里stackoverflow.com/questions/11116345/… 这是我试图从输出中得到的,虽然我在这里发布的输出没有那个字符串。
    • 试试这个正则表达式:/^(32)\s+?\S*\s+?\S*\s+?\S*\s+?\S*\s+?\S*\s+?\S*\s+?(\S*)/m ... 这将根据您的列拆分匹配,而不是最后的任意空格,这在您的系统上似乎有所不同。它还将匹配一个空行,最后一列没有输出,具有空值。
    • 试试 /.*^(32)\s+?\S*\s+?\S*\s+?\S*\s+?\S*\s+?\S*\s+?\S*\s+?(\S*)$.*/ 我认为这只会吸出 32 行的状态,没有别的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-21
    相关资源
    最近更新 更多