2011-06-07 24 views

Respuesta

16

¿Tiene la extensión SSH2 disponible?

Docs: http://www.php.net/manual/en/function.ssh2-exec.php

$connection = ssh2_connect('shell.example.com', 22); 
ssh2_auth_password($connection, 'username', 'password'); 

$stream = ssh2_exec($connection, '/usr/local/bin/php -i'); 
+1

No se puede obtener el módulo SSH2 sangrienta ir, conseguir lo siguiente en el registro de errores: PHP Warning: PHP inicio: ssh2: No se puede inicializar el módulo módulo compilado con módulo de API = 20050922 PHP compilado con módulo API = 20090626 Estas opciones deben coincidir con en Desconocido en la línea 0 – Justin

+0

¿Qué sistema operativo y versión, y qué versión de PHP? –

+2

También tenga en cuenta que debe tener OpenSSL y libssh2 para que el módulo ssh2 funcione correctamente. Si está compilando PHP manualmente, debe asegurarse de tener versiones compatibles de los dos módulos requeridos. Este error es indicativo de una falta de coincidencia en las versiones. –

2

utilizar las funciones ssh2. Todo lo que haría a través de una llamada a exec() se puede hacer directamente usando estas funciones, ahorrándole muchas conexiones e invocaciones de shell.

10

Lo he pasado mal con ssh2 en php principalmente porque el flujo de salida a veces funciona y otras veces no. Voy a pegar mi lib aquí que me funciona muy bien. Si hay pequeñas inconsistencias en código es porque lo tengo enchufado en un marco, pero que debe estar bien portarlo:

<?php 

class Components_Ssh { 

    private $host; 

    private $user; 

    private $pass; 

    private $port; 

    private $conn = false; 

    private $error; 

    private $stream; 

    private $stream_timeout = 100; 

    private $log; 

    private $lastLog; 

    public function __construct ($host, $user, $pass, $port, $serverLog) { 
     $this->host = $host; 
     $this->user = $user; 
     $this->pass = $pass; 
     $this->port = $port; 
     $this->sLog = $serverLog; 

     if ($this->connect()->authenticate()) { 
      return true; 
     } 
    } 

    public function isConnected() { 
     return (boolean) $this->conn; 
    } 

    public function __get ($name) { 
     return $this->$name; 
    } 

    public function connect() { 
     $this->logAction ("Connecting to {$this->host}"); 
     if ($this->conn = ssh2_connect ($this->host, $this->port)) { 
      return $this; 
     } 
     $this->logAction ("Connection to {$this->host} failed"); 
     throw new Exception ("Unable to connect to {$this->host}"); 
    } 

    public function authenticate() { 
     $this->logAction ("Authenticating to {$this->host}"); 
     if (ssh2_auth_password ($this->conn, $this->user, $this->pass)) { 
      return $this; 
     } 
     $this->logAction ("Authentication to {$this->host} failed"); 
     throw new Exception ("Unable to authenticate to {$this->host}"); 
    } 

    public function sendFile ($localFile, $remoteFile, $permision = 0644) { 
     if (! is_file ($localFile)) throw new Exception ("Local file {$localFile} does not exist"); 
     $this->logAction ("Sending file $localFile as $remoteFile"); 

     $sftp = ssh2_sftp ($this->conn); 
     $sftpStream = @fopen ('ssh2.sftp://' . $sftp . $remoteFile, 'w'); 
     if (! $sftpStream) { 
      // if 1 method failes try the other one 
      if (! @ssh2_scp_send ($this->conn, $localFile, $remoteFile, $permision)) { 
       throw new Exception ("Could not open remote file: $remoteFile"); 
      } 
      else { 
       return true; 
      } 
     } 

     $data_to_send = @file_get_contents ($localFile); 

     if (@fwrite ($sftpStream, $data_to_send) === false) { 
      throw new Exception ("Could not send data from file: $localFile."); 
     } 

     fclose ($sftpStream); 

     $this->logAction ("Sending file $localFile as $remoteFile succeeded"); 
     return true; 
    } 

    public function getFile ($remoteFile, $localFile) { 
     $this->logAction ("Receiving file $remoteFile as $localFile"); 
     if (ssh2_scp_recv ($this->conn, $remoteFile, $localFile)) { 
      return true; 
     } 
     $this->logAction ("Receiving file $remoteFile as $localFile failed"); 
     throw new Exception ("Unable to get file to {$remoteFile}"); 
    } 

    public function cmd ($cmd, $returnOutput = false) { 
     $this->logAction ("Executing command $cmd"); 
     $this->stream = ssh2_exec ($this->conn, $cmd); 

     if (FALSE === $this->stream) { 
      $this->logAction ("Unable to execute command $cmd"); 
      throw new Exception ("Unable to execute command '$cmd'"); 
     } 
     $this->logAction ("$cmd was executed"); 

     stream_set_blocking ($this->stream, true); 
     stream_set_timeout ($this->stream, $this->stream_timeout); 
     $this->lastLog = stream_get_contents ($this->stream); 

     $this->logAction ("$cmd output: {$this->lastLog}"); 
     fclose ($this->stream); 
     $this->log .= $this->lastLog . "\n"; 
     return ($returnOutput) ? $this->lastLog : $this; 
    } 

    public function shellCmd ($cmds = array()) { 
     $this->logAction ("Openning ssh2 shell"); 
     $this->shellStream = ssh2_shell ($this->conn); 

     sleep (1); 
     $out = ''; 
     while ($line = fgets ($this->shellStream)) { 
      $out .= $line; 
     } 

     $this->logAction ("ssh2 shell output: $out"); 

     foreach ($cmds as $cmd) { 
      $out = ''; 
      $this->logAction ("Writing ssh2 shell command: $cmd"); 
      fwrite ($this->shellStream, "$cmd" . PHP_EOL); 
      sleep (1); 
      while ($line = fgets ($this->shellStream)) { 
       $out .= $line; 
       sleep (1); 
      } 
      $this->logAction ("ssh2 shell command $cmd output: $out"); 
     } 

     $this->logAction ("Closing shell stream"); 
     fclose ($this->shellStream); 
    } 

    public function getLastOutput() { 
     return $this->lastLog; 
    } 

    public function getOutput() { 
     return $this->log; 
    } 

    public function disconnect() { 
     $this->logAction ("Disconnecting from {$this->host}"); 
     // if disconnect function is available call it.. 
     if (function_exists ('ssh2_disconnect')) { 
      ssh2_disconnect ($this->conn); 
     } 
     else { // if no disconnect func is available, close conn, unset var 
      @fclose ($this->conn); 
      $this->conn = false; 
     } 
     // return null always 
     return NULL; 
    } 

    public function fileExists ($path) { 
     $output = $this->cmd ("[ -f $path ] && echo 1 || echo 0", true); 
     return (bool) trim ($output); 
    } 
} 
+1

Gracias! este ayudó bastante. Lo reescribí para usar la autenticación de clave pública/privada, pero la suspensión (1) mata mi productividad. Si tengo tiempo para encontrar un trabajo, te lo haré saber. ¡Gracias! – jbrahy

62

me gustaría utilizar phpseclib, a pure PHP SSH implementation. Un ejemplo:

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

$ssh = new Net_SSH2('www.domain.tld'); 
if (!$ssh->login('username', 'password')) { 
    exit('Login Failed'); 
} 

echo $ssh->exec('pwd'); 
echo $ssh->exec('ls -la'); 
?> 
+1

¿Pueden estos ser asíncronos? Necesito hablar con múltiples sistemas a la vez. ¿Puedo iniciar sesiones ssh múltiples y luego "seleccionar" (o sondear) en todas ellas? .. –

+2

Un poco. En realidad, tu pregunta sería más adecuada como una nueva en lugar de una respuesta, pero lo que sea. Puede hacer '$ ssh-> setTimeout (...)' para cada instancia de $ ssh y recorrerlos. El modo interactivo también podría ser mejor para ti porque leer y escribir son un tanto disjuntos. Del mismo modo, podría hacer que enablePTY() suponga que use '$ ssh-> exec()' con '$ ssh-> read()'/'$ ssh-> write()'. – neubert

+0

Observe que esta biblioteca no es compatible con readlink() – Alexander

Cuestiones relacionadas