1

I am trying to build a ssh script to run multiple commands on a host. My goal is get the output of each command. My target host is a cisco router and for the following script to execute more that one command i need to run it for each command i want to execute which is not a very elegant solution.

$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); }

I have created a loop because i was unable to get the output for each command in the same stream. Since i guess that the php is terminating the ssh connections at the end of each stream.

What i would like to achieve is to execute several commands and get the output in the same stream (if posible).

I am editing the post to answer the sugestions made by @Melvin Koopmans and @LSerni.

if i change the code as sugested (this was someting i also tried before) the second command returns an error. here is the cli output: the script changed:

$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);}

the output from 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

I am only getting the output from the first command "sh run int te 1/1".

1
  • Could you not implode the array with "&&" so that it does all commands one after another automatically? Commented Feb 16, 2017 at 8:42

2 Answers 2

1

You are repeating the connection stage. Try this instead:

$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);
}

I tested now on a Ubuntu machine (14.04-LTS), and it works:

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

...well, apart from the fact that I forgot an open console login on that machine :-(

Sign up to request clarification or add additional context in comments.

Comments

0

I wouldn't recommend initiating a new connection on every single loop, instead set the connection first then loop over an array of commands and push the output to an array. Like so:

$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);
}

This will push all of the output to the array $output.

Now you can loop over $output, or you can choose to give output the key of yoru command so you can access it:

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

And then, for example, call: $output['ls']

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.