前言
在写项目中发现需要使用到一些ssh去操作Linux的一些命令。然后对此展开了一个研究调研,看一下有能否哪一些框架适合现在去做一些对应的ssh的操作。这一些复杂的命令,选择一个合适的框架是非常重要的。有的时候当你可能去实现某一些业务的时候,发现其中的某一个类没有你想要的方法。这就比较苦恼,也不可能短时间内去跟作者提issue。因为那需要很漫长的时间。
Java可以使用SSH的框架有哪些
- Apache MINA SSHD (Apache MINA是一个网络应用程序框架,它包括一个SSH服务器实现,可以用于构建自定义的SSH服务器应用程序。)
- JSch (JSch是一个纯Java实现的SSH2协议的客户端,可以用于在Java应用程序中执行远程命令和传输文件。)
- Ganymed SSH-2 for Java (Ganymed是一个基于Java的SSH-2协议客户端库,可用于在Java应用程序中进行SSH连接和文件传输。
jsch
这是一个用JAVA写的一个ssh的访问客户端,可以看到里面的工具类还是蛮多的。虽然star的数量没有多少,但是整体操作起来还是非常方便的。接下来是一些使用的demo示例。
代码示例
需要导入的maven包
代码语言:javascript复制<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
以下是一个简单的示例代码,使用JSch库连接到Linux服务器并读取目录:
代码语言:java复制import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import java.util.Vector;
public classSSHExampleSSHExample {
public static void main(String[] args) {
String host = "your_hostname";
String user = "your_username";
String password = "your_password";
int port = 22;
try {
JSch jsch = new JSch();
Session session = jsch.getSession(user, host, port);
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp");
channelSftp.connect();
String remoteDirectory = "/path/to/remote/directory";
Vector<ChannelSftp.LsEntry> list = channelSftp.ls(remoteDirectory);
for (ChannelSftp.LsEntry entry : list) {
if (entry.getAttrs().isDir()) {
System.out.println("Directory: " entry.getFilename());
}
}
channelSftp.disconnect();
session.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
}
打印的内容如下
代码语言:javascript复制Directory: .
Directory: ..
Directory: boot
Directory: dev
Directory: proc
Directory: run
Directory: sys
Directory: etc
Directory: root
Directory: var
Directory: tmp
Directory: usr
Directory: media
Directory: mnt
Directory: opt
Directory: srv
Directory: data
Ganymed SSH-2
这也是一个基于JAVA写的一个ssh的客户端框架。使用体验上来看。他也只是基于文件流做一个简单的一些数量读取,内容读取。
代码示例
导入的maven包
代码语言:javascript复制<dependency>
<groupId>ch.ethz.ganymed</groupId>
<artifactId>ganymed-ssh2</artifactId>
<version>build210</version>
</dependency>
这段代码主要是连接到Linux服务器,打印出指定目录下的所有子目录:
代码语言:java复制import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class SSHExample {
public static void main(String[] args) {
String hostname = "your_hostname";
String username = "your_username";
String password = "your_password";
String directory = "/path/to/remote/directory";
try {
Connection conn = new Connection(hostname);
conn.connect();
boolean isAuthenticated = conn.authenticateWithPassword(username, password);
if (isAuthenticated) {
Session sess = conn.openSession();
sess.execCommand("ls -l " directory);
InputStream stdout = sess.getStdout();
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
sess.close();
conn.close();
} else {
System.out.println("Authentication failed.");
}
} catch (IOException e) {
e.printStackTrace(System.err);
}
}
}
打印内容如下
代码语言:javascript复制total 28
lrwxrwxrwx. 1 root root 7 Oct 29 2021 bin -> usr/bin
dr-xr-xr-x. 5 root root 4096 Oct 25 10:03 boot
drwxr-xr-x 17 root root 4096 Oct 30 15:51 data
drwxr-xr-x 19 root root 3080 Oct 25 10:02 dev
drwxr-xr-x. 86 root root 8192 Dec 15 13:36 etc
lrwxrwxrwx 1 root root 10 Jun 24 2023 home -> /data/home
lrwxrwxrwx. 1 root root 7 Oct 29 2021 lib -> usr/lib
lrwxrwxrwx. 1 root root 9 Oct 29 2021 lib64 -> usr/lib64
drwxr-xr-x. 2 root root 6 Apr 11 2018 media
drwxr-xr-x. 3 root root 17 Nov 29 13:58 mnt
drwxr-xr-x. 15 root root 4096 Nov 22 14:37 opt
dr-xr-xr-x 364 root root 0 Oct 25 10:02 proc
dr-xr-x---. 21 root root 4096 Jan 5 09:30 root
drwxr-xr-x 29 root root 940 Dec 21 14:27 run
lrwxrwxrwx. 1 root root 8 Oct 29 2021 sbin -> usr/sbin
drwxr-xr-x. 3 root root 42 Oct 21 2022 srv
dr-xr-xr-x 13 root root 0 Oct 26 08:38 sys
drwxrwxrwt. 9 root root 271 Jan 16 15:01 tmp
drwxr-xr-x. 14 root root 171 Nov 1 2021 usr
drwxr-xr-x. 19 root root 267 Oct 29 2021 var
Apache SSHD
这是一个谷歌的阿帕奇开源的一个框架。虽然说关注的数量没有太多,但总体而言还是挺好的对于一些文件权限的一些操作细粒度还是会差一点。主要是它里面的一些操作。也是一些文件流的操作。
代码示例
maven导入的包
代码语言:javascript复制 <dependency>
<groupId>org.apache.sshd</groupId>
<artifactId>sshd-core</artifactId>
<version>2.7.0</version>
</dependency>
当使用Apache SSHD库读取Linux目录时,你可以使用以下示例代码。这段代码连接到Linux服务器并读取指定目录的内容,并将其打印到控制台上。
代码语言:java复制package org.example.ssh;
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.channel.ChannelExec;
import org.apache.sshd.client.channel.ClientChannelEvent;
import org.apache.sshd.client.future.ConnectFuture;
import org.apache.sshd.client.session.ClientSession;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.EnumSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* @author Steven
* @Date 2024/1/16 16:16
*/
public class SshClientExampleTwo {
public static void main(String[] args) throws IOException {
String host = "your_hostname";
String user = "your_username";
String password = "your_password";
String cmd = "ls / ";
SshClient client = SshClient.setUpDefaultClient();
try {
// Open the client
client.start();
// Connect to the server
ConnectFuture cf = client.connect(user, host, 22);
ClientSession session = cf.verify().getSession();
session.addPasswordIdentity(password);
long timeout = 10;
session.auth().verify(TimeUnit.SECONDS.toMillis(timeout));
// Create the exec and channel its output/error streams
ChannelExec ce = session.createExecChannel(cmd);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayOutputStream err = new ByteArrayOutputStream();
ce.setOut(out);
ce.setErr(err);
// Execute and wait
ce.open();
Set<ClientChannelEvent> events =
ce.waitFor(EnumSet.of(ClientChannelEvent.CLOSED), TimeUnit.SECONDS.toMillis(timeout));
session.close(false);
// Check if timed out
if (events.contains(ClientChannelEvent.TIMEOUT)) {
throw new RuntimeException(host " 命令 " cmd "执行超时 " timeout);
}
System.out.println(out.toString() " " err.toString() " " ce.getExitStatus());
} finally {
client.stop();
}
}
}
打印的内容如下
代码语言:javascript复制bin
boot
data
dev
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
0
总结
整体而言,使用jsch框架会比较适合用做那种权限比较多的做一些复杂操作的场景。阿帕奇这个框架我还是很看好的。毕竟是阿帕奇开源出来的。但是当他执行命令的时候,有些时候我需要读取某个指令文件的权限,文件大小还有一些特殊的文件处理就比较难搞了。有一些特殊的类没有找到。
目前这个博客只是用一些demo做一个简单的介绍。分析可以使用ssh访问方式的一些框架。
最后
点赞关注评论一键三连,每周分享技术干货、开源项目、实战经验、国外优质文章翻译等,您的关注将是我的更新动力
我正在参与2024腾讯技术创作特训营第五期有奖征文,快来和我瓜分大奖!