使用python或java直接进行ssh远程控制云服务器(以autodl为例)
python代码如下:
import paramiko
class SSHManager:
def __init__(self, host, port, username, password):
self.host = host
self.port = port
self.username = username
self.password = password
def connect(self):
self.client = paramiko.SSHClient()
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.client.connect(self.host, port=self.port, username=self.username, password=self.password)
def upload_file(self, local_path, remote_path):
ftp_client = self.client.open_sftp()
ftp_client.put(local_path, remote_path)
ftp_client.close()
def download_file(self, remote_path, local_path):
ftp_client = self.client.open_sftp()
ftp_client.get(remote_path, local_path)
ftp_client.close()
def execute_command(self, command):
stdin, stdout, stderr = self.client.exec_command(command)
print("命令执行结果:")
for line in stdout:
print(line.strip())
def close(self):
self.client.close()
# 连接参数
host = "xxxx"
port = 22 # 默认 SSH 端口
username = "xxx"
password = "xxxx"
# 实例化 SSHManager
ssh_manager = SSHManager(host, port, username, password)
# 连接到远程服务器
ssh_manager.connect()
# 执行命令
command = "mkdir xxxx"
ssh_manager.execute_command(command)
# 关闭连接
ssh_manager.close()
java代码如下:
import com.jcraft.jsch.*;
import java.io.*;
public class SSHManager {
private String host;
private int port;
private String username;
private String password;
public SSHManager(String host, int port, String username, String password) {
this.host = host;
this.port = port;
this.username = username;
this.password = password;
}
public void uploadFile(String localFilePath, String remoteFilePath) {
JSch jsch = new JSch();
Session session = null;
ChannelSftp channelSftp = null;
try {
session = jsch.getSession(username, host, port);
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
channelSftp = (ChannelSftp) session.openChannel("sftp");
channelSftp.connect();
channelSftp.put(localFilePath, remoteFilePath);
} catch (JSchException | SftpException e) {
e.printStackTrace();
} finally {
if (channelSftp != null) {
channelSftp.disconnect();
}
if (session != null) {
session.disconnect();
}
}
}
public void downloadFile(String remoteFilePath, String localFilePath) {
JSch jsch = new JSch();
Session session = null;
ChannelSftp channelSftp = null;
try {
session = jsch.getSession(username, host, port);
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
channelSftp = (ChannelSftp) session.openChannel("sftp");
channelSftp.connect();
channelSftp.get(remoteFilePath, localFilePath);
} catch (JSchException | SftpException e) {
e.printStackTrace();
} finally {
if (channelSftp != null) {
channelSftp.disconnect();
}
if (session != null) {
session.disconnect();
}
}
}
public void executeCommand(String command) {
JSch jsch = new JSch();
Session session = null;
ChannelExec channelExec = null;
try {
session = jsch.getSession(username, host, port);
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
channelExec = (ChannelExec) session.openChannel("exec");
BufferedReader in = new BufferedReader(new InputStreamReader(channelExec.getInputStream()));
channelExec.setCommand(command);
channelExec.connect();
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
} catch (JSchException | IOException e) {
e.printStackTrace();
} finally {
if (channelExec != null) {
channelExec.disconnect();
}
if (session != null) {
session.disconnect();
}
}
}
public static void main(String[] args) {
String host = "your_server_ip";
int port = 22;
String username = "your_username";
String password = "your_password";
SSHManager sshManager = new SSHManager(host, port, username, password);
// 上传文件
sshManager.uploadFile("/path/to/local/file.txt", "/path/to/remote/file.txt");
// 下载文件
sshManager.downloadFile("/path/to/remote/file.txt", "/path/to/local/file.txt");
// 执行命令
sshManager.executeCommand("ls -l /path/to/directory");
}
}
但是以上方法只能进行文件上传、文件下载以及简单的一些linux命令,故可以通过以下方法:
python代码:
import paramiko
import os
import select
import sys
# 建立一个socket
trans = paramiko.Transport(('hostname', 端口))
# 启动一个客户端
trans.start_client()
# 如果使用rsa密钥登录的话
'''
default_key_file = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa')
prikey = paramiko.RSAKey.from_private_key_file(default_key_file)
trans.auth_publickey(username='super', key=prikey)
'''
# 如果使用用户名和密码登录
trans.auth_password(username='root', password='密码')
# 打开一个通道
channel = trans.open_session()
# 获取终端
channel.get_pty()
# 激活终端,这样就可以登录到终端了,就和我们用类似于xshell登录系统一样
channel.invoke_shell()
# 下面就可以执行你所有的操作,用select实现
# 对输入终端sys.stdin和 通道进行监控,
# 当用户在终端输入命令后,将命令交给channel通道,这个时候sys.stdin就发生变化,select就可以感知
# channel的发送命令、获取结果过程其实就是一个socket的发送和接受信息的过程
while True:
readlist, writelist, errlist = select.select([channel, sys.stdin,], [], [])
# 如果是用户输入命令了,sys.stdin发生变化
if sys.stdin in readlist:
# 获取输入的内容
input_cmd = sys.stdin.read(1)
# 将命令发送给服务器
channel.sendall(input_cmd)
# 服务器返回了结果,channel通道接受到结果,发生变化 select感知到
if channel in readlist:
# 获取结果
result = channel.recv(1024)
# 断开连接后退出
if len(result) == 0:
print("\r\n**** EOF **** \r\n")
break
# 输出到屏幕
sys.stdout.write(result.decode())
sys.stdout.flush()
# 关闭通道
channel.close()
# 关闭链接
trans.close()