【问题标题】:PHP exec() line length (chars per line)PHP exec() 行长(每行字符)
【发布时间】:2014-07-08 16:01:22
【问题描述】:

我正在尝试通过 exec() 从命令行读取信息;

function ex($cmd){

    @exec($cmd,$exec,$status);

    if($status == 0){
        return $exec;   
    }
    return "";

}

我正在尝试“逐行”解析输出,但问题是输出行被拆分(就像终端窗口“太小”一样)。对于解析来说,如果输出没有“行长度限制”,并且无论大小如何,一行都会保留一行。

如何存档?

【问题讨论】:

  • 你在运行什么命令?大多数命令不关心窗口大小,尤其是在输出未定向到终端时。
  • 在调用exec之前尝试putenv("COLUMNS=1000");
  • 我正在运行apt-get --just-print upgrade,我只是尝试了“putenv”,但它没有改变任何东西:(
  • 不确定这是否有帮助,但是否有机会将apt-get upgrade --justprint 的输出传送到cat 或类似的东西?要查看问题,您可以尝试以下操作: 将窗口大小调整为大约 20 列并运行命令。之后将其调整为大约 200 列。当然,反过来它也很完美。
  • apt-get 需要有一个宽度来打印其进度条:否则它将如何工作?如果您想出于自己的目的捕获其输出,我至少会使用 -q 选项来禁用进度条。

标签: php shell exec


【解决方案1】:

使用 proc_open() 的解决方法。它很昂贵,但这应该可以为您提供命令的确切输出:

<?php
$descriptorspec = array(
   0 => array("pipe", "r"),
   1 => array("pipe", "w")
);

$shell = '/bin/bash';
$command = 'apt-get --just-print upgrade';

$process = proc_open($shell, $descriptorspec, $pipes);

if (is_resource($process)) {

    fwrite($pipes[0], $command);
    fclose($pipes[0]);

    $output = stream_get_contents($pipes[1]);
    fclose($pipes[1]);

    proc_close($process);
}

//$output holds the output in a single string

$lines = explode("\n", $output); // the full lines as array

【讨论】:

    【解决方案2】:

    为什么不直接使用 exec 并获取其输出。例如

    $output=exec("ls -la");
    

    然后你可以随意研究输出:

    $lines = explode("\n",$output);
    foreach($lines as $line)
       echo $line."<br>";
    

    另一方面,你可以使用 passtrhu 函数http://php.net/manual/en/function.passthru.php

    【讨论】:

    • 这并没有改变问题,因为输出中有“\n”,由于解析问题我不想在那里(它们在那里是因为“终端”是小而没有说明任何内容)。
    • 您是否尝试将命令保存在文件中然后研究它?例如ls -la &gt; myFile.txt。其他选择是做一个子字符串数组,然后将它们连接起来。请问你用什么类型的终端有这个问题,因为php cli对屏幕大小没有影响。
    • 尝试了“放入文件”解决方案,但这些行甚至比 exec/shell_exec() 的输出“更小”
    • 您是否尝试使用 sed 命令删除结果文件中的“\n”。 stackoverflow.com/questions/1251999/…
    【解决方案3】:

    您可以使用 shell_exec 运行它,将所有输出流作为字符串返回。另一方面 exec 只返回输出的最后一行。

    <?php
    
    function ex($cmd) {
        return explode("\n", shell_exec($cmd));
    }
    
    $output = ex('apt-get --just-print upgrade');
    
    var_dump($output);
    

    【讨论】:

    • 我已经得到了单行,但是输出被分成单行,这是一种“意外”的行为。
    【解决方案4】:

    由于其他解决方案不能解决问题或成本高,我使用了以下代码,虽然不是很通用,但可以解决问题:

    $str = ""; $versions['upgrades'] = array(); $addLines = 0;
    
    for($i = 0; $i < count($v); $i++){
        if(preg_match("~[0-9]+ upgraded~",$v[$i])){
            $str = $v[$i];
            break;
        }
        if($addLines == 1){
            $versions['upgrades'] = array_merge($versions['upgrades'],array_values(explode(' ',trim($v[$i]))));
        }
        if(preg_match("~will be upgraded~",$v[$i])){
            $addLines = 1;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多