jsch是一个提供java ssh远程连接和执行命令的工具jar包,其中关于执行命令时两种方式:
1、ChannelExec channel = (ChannelExec) session.openChannel("exec");
2、ChannelShell channel = (ChannelShell) session.openChannel("shell");
以下给出方法样列:
<!-- jsch支持 -->
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
package cn.objectspace.webssh.websocket;
import cn.hutool.core.io.IoUtil;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelShell;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class JSchDemo {
private String ipAddress; //主机ip
private String username; // 账号
private String password; // 密码
private int port; // 端口号
Session session;
public JSchDemo(String ipAddress, String username, String password, int port) {
this.ipAddress = ipAddress;
this.username = username;
this.password = password;
this.port = port;
}
public void connect() {
try {
JSch jsch = new JSch();
session = jsch.getSession(username, ipAddress, port);
session.setPassword(password);
//设置首次登录跳过主机检查
session.setConfig("StrictHostKeyChecking", "no");
//设置登录超时时间
session.connect(3000);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public int executeExec(String command) {
int returnCode = 0;
ChannelExec channel = null;
PrintWriter printWriter = null;
BufferedReader input = null;
try {
channel = (ChannelExec) session.openChannel("exec");
channel.setCommand(command);
InputStream in = channel.getInputStream();
channel.connect();
BufferedReader inputReader = new BufferedReader(new InputStreamReader(in, "GBK"));
String inputLine;
while ((inputLine = inputReader.readLine()) != null) {
System.out.println(inputLine);
}
} catch (Exception e) {
System.out.println(e.getMessage());
return -1;
} finally {
IoUtil.close(printWriter);
IoUtil.close(input);
if (channel != null) {
channel.disconnect();
}
}
return returnCode;
}
public int executeShell(String command) {
int returnCode = 0;
ChannelShell channel = null;
PrintWriter printWriter = null;
BufferedReader input = null;
StringBuffer stringBuffer = new StringBuffer();
try {
channel = (ChannelShell) session.openChannel("shell");
channel.connect();
//获取输入
InputStreamReader inputStreamReader = new InputStreamReader(channel.getInputStream());
input = new BufferedReader(inputStreamReader);
//输出
printWriter = new PrintWriter(channel.getOutputStream());
printWriter.println(command);
printWriter.println("exit");
printWriter.flush();
String line;
while ((line = input.readLine()) != null) {
stringBuffer.append(line + "\n") ;
}
System.out.println("输出:\n" + stringBuffer);
} catch (Exception e) {
System.out.println(e.getMessage());
return -1;
}finally {
IoUtil.close(printWriter);
IoUtil.close(input);
if (channel != null) {
channel.disconnect();
}
}
return returnCode;
}
public void close(){
if (session != null) {
session.disconnect();
}
}
}
这两种执行.sh脚本时存在差别,例如有一个test.sh脚本,在服务器/home目录下,且已经给予权限
chmod +x /home/test.sh
#!/bin/bash
mkdir -p /home/test
调用时会发现二者的差异
public class test {
public static void main(String[] args) {
JSchDemo jSchDemo = new JSchDemo("192.168.1.180", "root", "", 22);
jSchDemo.connect();
jSchDemo.executeExec("pwd");
System.out.println("========");
jSchDemo.executeExec("/home/test.sh");
//jSchDemo.executeShell("/home/test.sh");
jSchDemo.executeShell("ls /home");
jSchDemo.close();
}
}
当你使用ChannelExec,会发现目录/home/test目录并没有创建
jSchDemo.executeExec("/home/test.sh");
/home
========
而当使用ChannelShell,则创建正常
jSchDemo.executeShell("/home/test.sh");
/home
========
test
移除创建的文件夹
rm -rf /home/test
对于ChannelExec,正确的执行.sh脚本命令是,即前面加上sh
jSchDemo.executeExec("sh /home/test.sh");
/home
========
test
不知道ChannelExec执行.sh脚本是否还有其他方式,希望大佬们有建议则在评论区留个言
另外,如果需要后台执行某个命令,不能直接 <命令> + & 的方式执行,这样可能在 JSch 中不生效,建议写成这样的格式:<命令> > /dev/null 2>&1 &
文档引用: