skyfeathers

导航

[转载]php中的ssh2

1、  前言
为了能够让管理员直接选择好若干主机及机房然后直接将命令推送到各个主机上去执行。现整理了一下php里面的ssh2模块。方便使用。
2、  完整的类代码如下
<?php
// ssh protocols
// note: once openShell method is used, cmdExec does not work
class ssh2 {
   private $host = 'host';
  private $user = 'user';
  private $port = '22';
  private $password = 'password';
  private $con = null;
  private $shell_type = 'xterm';
  private $shell = null;
  private $log = '';
  function __construct($host='', $port=''  ) {
     if( $host!='' ) $this->host  = $host;
     if( $port!='' ) $this->port  = $port;
     $this->con  = ssh2_connect($this->host, $this->port);
     if( !$this->con ) {
       $this->log .= "Connection failed !";
     }
  }
  function authPassword( $user = '', $password = '' ) {
     if( $user!='' ) $this->user  = $user;
     if( $password!='' ) $this->password  = $password;
     if( !ssh2_auth_password( $this->con, $this->user, $this->password ) ) {
       $this->log .= "Authorization failed !";
     }
  }
  function openShell( $shell_type = '' ) {
    if ( $shell_type != '' ) $this->shell_type = $shell_type;
    $this->shell = ssh2_shell( $this->con,  $this->shell_type );
    if( !$this->shell ) $this->log .= " Shell connection failed !";
    stream_set_blocking( $this->shell, true );
  }
  function writeShell( $command = '' ) {
    fwrite($this->shell, $command."\n");
  }
  function cmdExec( ) {
        $argc = func_num_args();
        $argv = func_get_args();
    $cmd = '';
    for( $i=0; $i<$argc ; $i++) {
        if( $i != ($argc-1) ) {
          $cmd .= $argv[$i]." && ";
        }else{
          $cmd .= $argv[$i];
        }
    }
    echo $cmd;
    $stream = ssh2_exec( $this->con, $cmd );
    stream_set_blocking( $stream, true );
       return stream_get_contents($stream);
  }
  function getLog() {
     return $this->log;
  }
    function getResult(){
        $contents='';
    while (!feof($this->shell)) {
        $contents.=fgets($this->shell);
    }
    return $contents;
    }
}
?>
3、  几点说明
ssh2_exec() 一次只能執行一個指令,也就是說,在執行完ssh2_exec()之後,PHP就會將連線中斷,下一個ssh2_exec()執行 時,會重新Login進去執行,也就是說指令之間是不會有關聯性的,這對網路設備來說是非常不合理的,因為有用過網路設備的都知道,要完成一項作業可能會 需要很多道指令,每個指令可能都有階層式關係,我目前的解法是在每個指令後用換行符號接起來,eg."config firewall policy \n edit 1\n"。(多个指令的时候可以这样解决)
不過因為ssh2_shell()不會主動中斷連線,使用時 (Class裡面的openShell跟writeShell),記得要把logout的指令一並執行,不然程式會hang住
(要将logout指令跑一下表示用户正常退出掉)
4、  调用示例
include_once 'ssh2.php';
$shell = new ssh2("192.168.0.100");
$shell->authPassword("root","123456");
$shell->openShell("xterm");
$result=$shell->cmdExec("puppetrun -d --host 123456.puppet.test.com  -t abc >> /dev/null");
$shell->writeShell("exit");
echo $result;

posted on 2012-03-30 09:35  天羽  阅读(1062)  评论(0编辑  收藏  举报