【问题标题】:Empty PHP SSH2 stream contents, even with stream_set_blocking?空的 PHP SSH2 流内容,即使使用 stream_set_blocking?
【发布时间】:2010-12-05 15:24:10
【问题描述】:

我正在开发一种工具,该工具使用 PECL SSH2 扩展通过 SSH2 从远程主机读取 iptables 配置。我能够成功地与主机建立连接、身份验证和执行命令。我遇到的问题是有时流不包含任何数据。

 /**
  * Load the current firewall configuration
  * @return bool
  */
 public function loadRules() {
  $stream = ssh2_exec($this->connection,"~/iptsave;");
  stream_set_blocking($stream,true);
  $iptablesSave = stream_get_contents($stream);
  if(empty($iptablesSave)) {
   return false;
   }
  parent::restore($iptablesSave);
  return true;
  }

大约 25% 的时间,loadRules() 返回 false,即使连接到 locahost 而不是远程系统也是如此。我可以通过将 ssh2_exec 调用更改为

来解决该问题
$stream = ssh2_exec($this->connection,"~/iptsave; sleep .5");

但我担心出了点问题。

【问题讨论】:

  • 您的问题得到答案了吗?

标签: php ssh stream


【解决方案1】:

我在这里遇到了同样的问题。不知何故,您需要设置延迟以获取流的结果。

你做的方式是可能的,但你也可以在stream_set_block($stream, true)函数之后设置一个sleep(1)。 你可以试试usleep() 函数。还没试过

【讨论】:

  • 我认为这些解决方案不起作用,但我发现了我的错误。我附加到命令“2>&1”字符串的末尾,以便将标准错误重定向到标准输出。现在它可以工作了 :) 请查看此链接以获取更多信息:stackoverflow.com/questions/16665041/…
【解决方案2】:

phpSecLib 或许能帮上忙:

根据this post,它总是返回输出,不像ssh2.so。

【讨论】:

    【解决方案3】:

    也许这会解决问题:

    $stream = ssh2_exec($this->connection,"~/iptsave;");
    stream_set_blocking($stream,true);
    $stream_out = ssh2_fetch_stream($stream, SSH2_STREAM_STDIO);
    $iptablesSave = stream_get_contents($stream);
    

    【讨论】:

    • 我认为这些解决方案不起作用,但我发现了我的错误。我附加到命令“2>&1”字符串的末尾,以便将标准错误重定向到标准输出。现在它可以工作了 :) 请查看此链接以获取更多信息:stackoverflow.com/questions/16665041/…
    【解决方案4】:

    对于某些服务器,您必须使用“交互式外壳”。有时您必须手动设置延迟/睡眠。一个工作示例:

    $connection = ssh2_connect($IP, 22);
    $auth = ssh2_auth_password($connection, $User, $Pass);
    $cmd = "help" . PHP_EOL;
    if (!$auth) {
        echo "Login Failed;
        exit(1);
    }
    
    $shell = ssh2_shell($connection);
    
    stream_set_blocking($shell, false); // we will use manual sleep
    sleep(1); // This sleep to make sure that you get the prompt back
    
    fwrite ($shell, $cmd . ";" . PHP_EOL);
    sleep(1); // This to make sure that the command executes and we get the prompt back again!
    while($output = fgets($shell)){
       echo $output;
    }
    fwrite ($shell, "exit;" . PHP_EOL); // If needed
    sleep(1);
    
    ssh2_disconnect($connection);
    unset($shell);
    unset($connection);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多