【问题标题】:PHP SSH multiple commandsPHP SSH 多个命令
【发布时间】:2017-02-16 08:40:18
【问题描述】:

我正在尝试构建一个 ssh 脚本以在主机上运行多个命令。我的目标是获得每个命令的输出。我的目标主机是一台 cisco 路由器,为了让以下脚本执行多个命令,我需要为我想要执行的每个命令运行它,这不是一个非常优雅的解决方案。

$cmd = array ('sh run int te 1/1', 'sh run int te 1/2');

for ($i = 0; $i <= 1; $i++) {
    $connection = ssh2_connect('10.1.1.1', 22);
    ssh2_auth_password($connection, 'user', 'pass');
    $stream = ssh2_exec($connection, $cmd[$i]);
    stream_set_blocking($stream, true);
    $stream_out = ssh2_fetch_stream($stream, SSH2_STREAM_STDIO);
    echo stream_get_contents($stream_out); }

我创建了一个循环,因为我无法在同一流中获取每个命令的输出。因为我猜 php 在每个流的末尾终止了 ssh 连接。

我想要实现的是执行多个命令并在同一流中获取输出(如果可能)。

我正在编辑帖子以回答@Melvin Koopmans 和@LSerni 提出的建议。

如果我按照建议更改代码(这也是我之前尝试过的),第二个命令将返回错误。这是cli输出: 脚本改变了:

$cmds = array ('sh run int te 1/1', 'sh run int te 1/2');

$connection = ssh2_connect('10.1.1.1', 22);
ssh2_auth_password($connection, 'user', 'pass');

foreach ($cmds as $cmd) {
    $stream = ssh2_exec( $connection, $cmd );
    stream_set_blocking( $stream, true );
    $stream_out = ssh2_fetch_stream( $stream, SSH2_STREAM_STDIO );
    echo stream_get_contents($stream_out);}

cli 的输出

interface TenGigabitEthernet1/1
description trunk
switchport trunk allowed vlan 1,2,3,4,5,6,10
switchport mode trunk
auto qos trust
storm-control broadcast include multicast
storm-control broadcast level 1.00
spanning-tree guard loop
service-policy input AutoQos-4.0-Input-Policy
service-policy output AutoQos-4.0-Output-Policy
ip dhcp snooping trust
end

PHP Warning:  ssh2_exec(): Unable to request a channel from remote host       in C:\Users\SMS\Downloads\php_scripts\ssh.php on line 13
PHP Warning:  stream_set_blocking() expects parameter 1 to be resource, boolean given in C:\Users\SMS\Downloads\php_scripts\ssh.php on line 14
PHP Warning:  ssh2_fetch_stream() expects parameter 1 to be resource, boolean given in C:\Users\SMS\Downloads\php_scripts\ssh.php on line 15
PHP Warning:  stream_get_contents() expects parameter 1 to be resource, null given in C:\Users\SMS\Downloads\php_scripts\ssh.php on line 16

我只得到第一个命令“sh run int te 1/1”的输出。

【问题讨论】:

  • 你能不能用“&&”使数组内爆,让它自动一个接一个地执行所有命令?

标签: php ssh


【解决方案1】:

您正在重复连接阶段。试试这个:

$cmds = array ('sh run int te 1/1', 'sh run int te 1/2');

$connection = ssh2_connect('10.1.1.1', 22);
ssh2_auth_password($connection, 'user', 'pass');

foreach ($cmds as $cmd) {
    $stream = ssh2_exec($connection, $cmd);
    stream_set_blocking($stream, true);
    $stream_out = ssh2_fetch_stream($stream, SSH2_STREAM_STDIO);
    echo stream_get_contents($stream_out);
}

我现在在 Ubuntu 机器 (14.04-LTS) 上进行了测试,它可以工作:

I say 'who', answer was: lserni   :0           Jan 21 11:25 (console)
I say 'date', answer was: Thu Feb 16 09:55:52 CET 2017

...好吧,除了我忘记在那台机器上打开控制台登录这一事实:-(

【讨论】:

    【解决方案2】:

    我不建议在每个循环上都启动一个新连接,而是先设置连接,然后遍历一个命令数组并将输出推送到一个数组。像这样:

    $cmds = [ 'ls', 'ps ux' ];
    
    $connection = ssh2_connect( '127.0.0.1', 22 );
    ssh2_auth_password( $connection, 'username', 'password' );
    
    $output = [];
    
    foreach ($cmds as $cmd) {
        $stream = ssh2_exec( $connection, $cmd );
        stream_set_blocking( $stream, true );
        $stream_out = ssh2_fetch_stream( $stream, SSH2_STREAM_STDIO );
        $output[] = stream_get_contents($stream_out);
    }
    

    这会将所有输出推送到数组$output

    现在你可以遍历 $output,或者你可以选择给输出 yoru 命令的键,这样你就可以访问它了:

    $output[$cmd] = stream_get_contents($stream_out);
    

    然后,例如,调用:$output['ls']

    【讨论】:

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