使用Net_SSH进行实时SSH输出(phpseclib)

时间:2017-09-12 12:12:57

标签: php ssh phpseclib

我使用Net_SSH(phpseclib)在外部服务器上执行SSH命令。我根本无法弄清楚如何从命令中获得实时输出。我知道如何让它在后台运行,因此它不依赖于Apache进程,但我不清楚我如何实时显示外部输出而不是必须等待命令完成。

我目前的代码就像$ssh->exec('command')一样简单。

使用的PHP版本是:

[admin@ ~]$ php -v
PHP 7.1.9 (cli) (built: Sep 10 2017 11:31:06) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies

2 个答案:

答案 0 :(得分:0)

我设法使用libssh2和输出缓冲,请参见下面的示例:

$session = ssh2_connect("server.local", 22, array('hostkey'=> 'ssh-rsa' )) or die("Couldn't connect to the SSH Server.");

ssh2_auth_pubkey_file($session, "root", "/path/to/public/key.pub", "/path/to/private/key") or die("couldn't authenticate to server"); // Authenticating to the server with a ssh-key for security purposes

while (ob_end_flush()); // end all output buffers if any

$proc = ssh2_exec($session, "ping -c 40 google.nl");

echo '<pre class="scroll">';
echo "[root@server ~]# ping -c 5 google.nl\n"; // Command you will execute
while (!feof($proc))
{
    echo fread($proc, 4096); // Read the output from the command
    @ flush(); // Flushes the whole php buffer so we can output new data
}
echo "\nDone";
echo '</pre>';

不要忘记ssh2需要php 5.6或更低版本,你可以在使用它时用$ssh->exec('command')替换变量$ proc中的命令。

答案 1 :(得分:-1)

我能够使用它来实现它:

$ssh->exec('ping 127.0.0.1', function($output) {
    echo $output;
});

为了消除系统配置与我的系统的可变性,我将使用Vagrant建立通用配置。为此,这是我的Vagrantfile:

Vagrant.configure("2") do |config|
    config.vm.box = "ubuntu/trusty64"
end

我的完整phpseclib代码(使用1.0.7):

<?php
include('Net/SSH2.php');

$ssh = new Net_SSH2('127.0.0.1', 2222);
$ssh->login('vagrant', 'vagrant');

$ssh->exec('ping 127.0.0.1', function($output) {
    echo $output;
});

输出的YouTube视频:

https://youtu.be/j9-q3024eEk

如果它不起作用则存在几种可能性。

  1. 也许您正在运行的“命令”不会实时转储输出。或者它可能需要一个PTY或其他东西。很难评论,因为你还没有说出你想要运行的命令是什么。正如我的帖子所示, 命令是我的解决方案 所使用的。

  2. 也许它适用于Vagrant但不适用于您的系统。也许您的系统已经以某种时髦的方式配置。在这种情况下,我想如果你提供SSH日志会有什么帮助。您可以通过define('NET_SSH2_LOGGING', 2);然后echo $ssh->getLog();来获取它们。将结果发布在pastebin.com中,然后发布链接。

  3. 编辑:如果你在网络服务器和CLI中运行它,你可能会遇到网络服务器设置方式的问题 - 经过phpseclib的问题。例如,这是实时输出还是锁定?:

    while (true) {
        echo "test\n";
        sleep(1);
    }
    

    flush() / ob_flush()可能有所帮助,但最终这将取决于您正在使用的Web服务器(Apache,nginx等),您正在使用的SAPI(CGI,Apache模块等)等等。

    我认为这是一个“时髦的配置”。