PHP fread ssh stream significantly slow -


scenario: needed function stdout of command run through ssh asynchronously. has various uses including (and importantly) reading files through ssh. important feature of function is asynchronous, hence can display output returned server (or give estimate of file download progress). differs common approach of using ssh_move() download files.

function ssh_exec($dsn, $cmd, $return=true, $size_est=null){     $buffer_size = $return ? (1024 * 1024) : 1;     debug('ssh2_exec '.$cmd);     $stream = ssh2_exec(ssh_open($dsn), $cmd);     debug('stream_set_blocking');     stream_set_blocking($stream, true);     debug('ssh2_fetch_stream');     $stream_out = ssh2_fetch_stream($stream, ssh2_stream_stdio);     stream_set_blocking($stream_out, true);     debug('stream_get_contents');     $data = ''; $stime = $oldtime = microtime(true); $data_len = 0;     if(!$return){         write_message("\033[0m".'  execution output:'.php_eol.'    ');     }     while(!feof($stream_out)){         $buff = fread($stream_out, $buffer_size);         if($buff===false)throw new exception('unexpected result fread().');         if($buff===''){             debug('empty result fread()...breaking.');             break;         }         $data .= $buff;         if($return){             $buff_len = strlen($buff);             $data_len += $buff_len;             $newtime = microtime(true);             debugo('stream_get_contents '.bytes_to_human($data_len)                 .' @ '.bytes_to_human($buff_len / ($newtime - $oldtime)).'/s'                 .' ['.($size_est ? number_format($data_len / $size_est * 100, 2) : '???').'%]');             $oldtime = $newtime;         }else{             echo str_replace(php_eol, php_eol.'    ', $buff);         }     }     if($return){         debugo('stream_get_contents transferred '.bytes_to_human(strlen($data)).' in '.number_format(microtime(true) - $stime, 2).'s');         return $data;     } } 

usage: function used so:

$dsn = 'ssh2.exec://root:pass@host/'; $size = ssh_size($dsn, 'bigfile.zip'); $zip = ssh_exec($dsn, 'cat bigfile.zip', true, $size); 

note 1: explanation of non-standard functions:

  • debug($message) - writes debug message console.
  • ssh_open($dsn) - takes in ssh uri , returns ssh connection handle.
  • bytes_to_human($bytes) - converts number of bytes human readable format (eg: 6gb)
  • debugo($message) - same debug() overwrites last line.

note 2: parameter $size_est used in progress indicator; you'd first file size , attempt download (as in example). optional can ignored when want run ssh command.

the problem: running same download operation via scp root@host:/bigfile.zip ./, speeds 1mb/s whereas script seems limit 70kb/s. i'd know why , how improve this.

edit: also, i'd know how/if $buffer_size difference.

you should able use phpseclib, pure php ssh implementation, this. eg.

$ssh->exec('cat bigfile.zip', false);  while (true) {     $temp = $this->_get_channel_packet(net_ssh2_channel_exec);     if (is_bool($temp)) {         break;     }     echo $temp; } 

might faster too.


Comments

Popular posts from this blog

linux - Does gcc have any options to add version info in ELF binary file? -

javascript - Clean way to programmatically use CSS transitions from JS? -

android - send complex objects as post php java -