「这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战」。
本文介绍通过java向linux服务器发送执行命令,通常大家都是使用Xshell、FinalShell,使用java操作Linux,主要有三种方法:
1、使用JDK自带的RunTime类和Process实现本地操作linux服务器
2、使用ganymed-ssh2 操作远程linux服务器
3、使用jsch远程连接操作linux服务器
本文介绍后两种方法,在这之前先创建一个公共的方法,用于打印发送指令后返回的信息和异常信息
private String consumeStream(InputStream stdout) throws Exception {
// 执行之后的流
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
String s ;
StringBuilder sb = new StringBuilder();
while((s=br.readLine())!=null){
// 循环打印所有数据
sb.append(s);
System.out.println(s);
}
return sb.toString();
}
复制代码
使用ganymed-ssh2 操作远程linux服务器
通过maven引入jar包
<!-- ganymed-ssh2 远程调用linux -->
<dependency>
<groupId>ch.ethz.ganymed</groupId>
<artifactId>ganymed-ssh2</artifactId>
<version>262</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
复制代码
创建会话并发送命令
public void execGanymed() throws IOException {
// 连接服务器地址
Connection conn = new Connection("服务器ip地址",连接端口一般为22);
// 开启连接
conn.connect();
// 验证用户密码
conn.authenticateWithPassword("用户名", "密码");
// 创建链接的 session
Session session = conn.openSession();
// 执行命令
String execCode = "cd /data/jar/ming/ming-service/&&ls";
System.out.println("执行的命令: " + execCode);
session.execCommand(execCode);
// 消费所有输入流
String inStr = consumeStream(session.getStdout());
// 执行错误
String errStr = consumeStream(session.getStderr());
session.close();
conn.close();
}
复制代码
这里发送了两段代码:
1、进入 /data/jar/ming/ming-service 路径下
2、ls 命令查看文件夹下所有文件夹和文件
##jsch远程连接操作linux服务器
通过maven添加jar包
<!-- jsch 远程调用linux -->
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.51</version>
</dependency>
<dependency>
<groupId>org.apache.maven.archetype</groupId>
<artifactId>maven-archetype</artifactId>
<version>3.1.2</version>
</dependency>
复制代码
创建会话并发送命令
public void execJsch() throws Exception {
// 创建JSch
JSch jSch = new JSch();
// 获取session
Session session = jSch.getSession("用户名", "服务器ip地址", 连接地址一般为22);
session.setPassword("密码");
Properties prop = new Properties();
// 有三种配置
// StrictHostKeyChecking=no 使用用户名密码登录设置为这个,当然也是最不安全的连接方式
// StrictHostKeyChecking=ask 默认的安全机制
// StrictHostKeyChecking=yes 最高的安全机制
prop.put("StrictHostKeyChecking", "no");
session.setConfig(prop);
// 启动连接
session.connect();
ChannelExec exec = (ChannelExec)session.openChannel("exec");
// 注意这里执行要 java -jar 的命令需要把环境变量给加载进来,通过 source /etc/profile 这一句命令加载环境变量
// 其实最终我们需要的只是 jdk 加载好就行了
exec.setCommand("source /etc/profile &&cd /data/jar/ming/ming-service&&ls");
exec.setInputStream(null);
exec.setErrStream(System.err);
exec.connect();
// 消费所有输入流,必须在exec之后
String inStr = consumeInputStream(exec.getInputStream());
String errStr = consumeInputStream(exec.getErrStream());
exec.disconnect();
session.disconnect();
}
复制代码
这里发送了三段代码,每段代码直接使用 && 连接:
1、通过 source /etc/profile 命令添加环境变量
2、进入 /data/jar/ming/ming-service 路径下
3、ls 命令查看文件夹下所有文件夹和文件
可能遇到的问题
java.io.IOException: A remote execution has already started.
命令执行使用 execCommand ,每个session中只能执行一次execCommand,执行多次会报以上错误。
查看 jdk 安装路径
echo $JAVA_HOME