我有与以下问题类似的情况 SSH2 change a user password
唯一的区别是我的操作是“scp”,我想通过 PHP 发送 ssh 命令以使用 scp 命令将文件发送到远程机器(我知道 php 本身有实现此目的的方法,但由于某种原因,我跳过了该方法) .
Code is as follows
//run specified cmd with stream reading and writing
function runCMDAdvance($cmd){
if (strpos($cmd,'scp') !== false) {
//reply machine when ask for password in file transfer
$confirmPass = $this->password."\n".$this->password."\n";
if (!($stream = ssh2_exec($this->conn, $cmd )))
{
echo "fail: unable to execute command\n";
fclose($stream);
return ERROR_SSH_EXEC_COMM;
}
fwrite($stream,$confirmPass); //>>Actually I want to pass the password information by writing to the stream, but turn out that it does not work
stream_set_blocking($stream, true);
}
}
当我尝试在流集阻塞后写入密码信息时,php执行代码会卡住。(我猜原因是远程机器正在等待密码信息,但 php 无法提供密码信息,所以它只是继续等待并阻塞 php 运行线程。)
我已经阅读了上述问题,但似乎无法找到正确的方向来实现这一目标,对此有什么想法吗?
再次感谢大家的帮助!
参考neubert的回答,使用phpseclib还是不行...
//$cmd is $cmd = 'scp '.$scpPath.' root@'.$ip.':/root';
function runCMDAdvance($cmd, $tVal){
if (strstr($cmd,"scp")!==FALSE){
if((include('Net/SSH2.php')) && (include('Net/SCP.php'))){
//set ssh timeout value
$this->setTimeoutVar($tVal);
$ssh = new Net_SSH2($this->host);
if (!$ssh->login($this->username, $this->password)){
echo "Bad Login";
return false;
}
$ssh->write($cmd."\n");
$ssh->read(' password:');
$ssh->write($this->password."\n");
}
}
else{
echo "Wrong command used, please check your code";
return false;
}
}
我处理SSH读写流的解决方案
//run any specified cmd using ssh
//parameter:
//cmd>>running command
//tVal>>command run timeout
//return:terminal stdout
function runCMDAdvance($sshIP, $cmd, $tVal,$tarIP){
$ssh = new Net_SSH2($sshIP);
if (!$ssh->login($this->username, $this->password)){
echo "Bad Login";
return false;
}
//set timeout for running ssh command, should be done after the ssh object has been initialized
$ssh->setTimeout($tVal);
//scp action detected
if (strstr($cmd,"scp")!==FALSE){
//if this is the first time to do the ssh, connect with "yes" for answering
if ($ssh->write($cmd)){
//store the output of the text message given by the router
$ssh_stdout = $ssh->read();
//echo $ssh_stdout."|||";
if (strstr($ssh_stdout,'trusted ')!==FALSE){
$ssh->write("y\n");
//and ask password
$ssh->read(' :password');
}
//deal with known host situation
elseif (strstr($ssh_stdout,'ssh-keygen ')!==FALSE){
$ssh->write('ssh-keygen -f '.'/root/.ssh/known_hosts -R '.$tarIP."\n");
$ssh->write($cmd);
$ssh->read(' :password');
$ssh->write($this->password."\n");
return true;
}
//deal with still connecting situation
elseif (strstr($ssh_stdout,'Are you sure you want to continue connecting')!==FALSE){
$ssh->write("yes\n");
$ssh->read(' :password');
$ssh->write($this->password."\n");
return true;
}
$ssh->write($this->password."\n");
$returnRead = $ssh->read();
$ssh->disconnect();
return true;
}//end of inner inner if
}//end of scp if (deal with scp)
else{//if not scp action,just normal action,simply execute the command
//exec will not return anything if the command is not run successfully
$res = $ssh->exec($cmd);
$ssh->disconnect();
return $res;
}
}