一、关于JSCH技术的简单描述
JSCH是SSH的一个纯Java实现。说直白点,就是一个远程连接你其他Linux或者Unix服务器的一个java代码包。其实就是我们使用jsch这个jar包来方便我们编写代码来连接自己linux系统的。
SSH:是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。
二、使用JSCH的基本操作步骤
1.首先当然是基于Eclipse或者Intellij IDEA。安装教程数不胜数,在这里略过。
2.下载jsch的jar包并导入自己的项目目录中。
在https://mvnrepository.com/这个地址先下载jsch的jar包。
搜索jsch,找到一个合适的版本(就是使用人数比较多的版本,稳定)
点进去,再找到一个人数使用比较多的版本点击下载
下载
OK,下载完jar包之后在项目下新建一个folder文件夹,命名为lib(web项目在WEB-INF目录自带)。将jsch的jar包copy到lib目录下,后右键点击你的jar包,选择Build Path----->Add To Build Path。这样,jar包就已经导入你的项目中可以使用了。
3.编写jschutil工具类,用于连接Linux系统
代码如下:
/**
* java 使用jsch远程链接linux 执行命令
* @author Weikisa
*/
public class JSchUtil {
private static JSch jsch;//定义jsch连接类
private static Session session;
private static String user = "root";//Linux系统的用户名
private static String password = "R00tAtCT";//密码
private static String host = "10.129.93.85";//測試IP,實際使用以輸入IP地址為准
/**
* 首先连接服务器
* @throws JSchException
*/
public static void connect(String hostIP) throws JSchException {
jsch = new JSch();//将jsch实例化
session = jsch.getSession(user, hostIP, 22);//默认端口号为22端口,使用用户名user连接IP
session.setPassword(password);//设置登录密码
session.setConfig("StrictHostKeyChecking", "no");//是否使用密钥登录,一般默认为no
session.connect(60 * 1000);
}
/**
*連接測試
*/
public static boolean connectTest(String hostIP) {
boolean flag = false;
try {
connect(hostIP);
flag = true;
System.out.println("連接Linux成功");
} catch (Exception e) {
e.printStackTrace();
} finally{
session.disconnect();
}
return flag;
}
}
创建完以上工具类后,我们可以自己写一个main方法来测试连接功能。
public static void main(String[] args) {
JSchUtil jsch = new JSchUtil();
jsch.connectTest("10.129.93.85");
}
运行结果如下:
出现上述Console控制台的提示,说明我们已经可以通过java代码来连接Linux系统了。
三、实现java代码执行Linux的命令。
1.在你的JSchUtil工具类中 添加如下的新方法。
/**
* 连接服务器后执行相应的linux命令
* @param command
* @throws JSchException
*/
public boolean execCmd(String hostIP,String command) throws JSchException {
connect(hostIP);//连接指定IP地址的Linux
BufferedReader reader = null;
Channel channel = null;//定义流通道
try {
while (command != null) {
channel = session.openChannel("exec");
((ChannelExec) channel).setCommand(command);
channel.setInputStream(null);
((ChannelExec) channel).setErrStream(System.err);
// 获取流
InputStream in = channel.getInputStream();//定义输入的通道
channel.connect();//连接
byte[] tmp = new byte[1024];
while (true) {
while (in.available() > 0) {
int i = in.read(tmp, 0, 1024);
if (i < 0) break;
System.out.print(new String(tmp, 0, i));
}
if (channel.isClosed()) {
if (in.available() > 0) continue;
System.out.println("exit-status: " + channel.getExitStatus());
if(channel.getExitStatus()!=0){
return false;
}
break;
}
// try {
// Thread.sleep(1000);
// } catch (Exception ee) {
// }
}
channel.disconnect();
session.disconnect();
System.out.println("Linux指令執行結束");
return true;
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSchException e) {
e.printStackTrace();
} finally {// 最后流和连接的关闭
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}
添加完方法后,自然是进行测试。
这里我们使用简单的命令来测试命令是否执行成功。
2.在main方法中添加以下代码 ,用于测试
public static void main(String[] args) {
JSchUtil jsch = new JSchUtil();
try {
jsch.execCmd("10.129.93.85", "mkdir /weikisa");
} catch (Exception e) {
e.printStackTrace();
System.out.println("出現異常"+e.toString());
}
}
执行结果如下:
结果exit-status: 0意味着执行过程没有异常,执行成功。
为了进一步验证,我们使用Putty(你也可以使用X-shell)连接上我们的Linux系统验证一下weikisa这个文件夹是否真的被创建出来。
看到weikisa已经创建在根目录下(“/”),说明我们的命令已经得以执行。
3.在执行一次删除命令,看看。
执行无误,我们再回到Linux系统下看看。
weikisa目录已经被删除了,说明基本的命令执行也可以实现了。
在最后附上JSchUtil的完整代码
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Calendar;
import java.util.Random;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
/**
* java 使用jsch远程链接linux 执行命令
* @author Weikisa
*/
public class JSchUtil {
private static JSch jsch;
private static Session session;
private static String user = "root";
private static String password = "R00tAtCT";
private static String host = "10.129.93.85";//測試IP,實際使用以輸入IP地址為准
public static void main(String[] args) {
JSchUtil jsch = new JSchUtil();
try {
jsch.execCmd("你的Linux的IP地址", "mkdir /weikisa");
jsch.execCmd("你的Linux的IP地址", "rmdir /weikisa");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 首先连接服务器
* @throws JSchException
*/
public static void connect(String hostIP) throws JSchException {
jsch = new JSch();
session = jsch.getSession(user, hostIP, 22);
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");
session.connect(60 * 1000);
}
/**
*連接測試
*/
public static boolean connectTest(String hostIP) {
boolean flag = false;
try {
jsch = new JSch();
session = jsch.getSession(user, hostIP, 22);
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");
session.connect(60 * 1000);
flag = true;
System.out.println("連接Linux成功");
} catch (Exception e) {
e.printStackTrace();
} finally{
session.disconnect();
}
return flag;
}
/**
* 连接服务器后执行相应的linux命令
* @param command
* @throws JSchException
*/
public boolean execCmd(String hostIP,String command) throws JSchException {
connect(hostIP);
BufferedReader reader = null;
Channel channel = null;
try {
while (command != null) {
channel = session.openChannel("exec");
((ChannelExec) channel).setCommand(command);
channel.setInputStream(null);
((ChannelExec) channel).setErrStream(System.err);
// 获取流
InputStream in = channel.getInputStream();
channel.connect();
byte[] tmp = new byte[1024];
while (true) {
while (in.available() > 0) {
int i = in.read(tmp, 0, 1024);
if (i < 0) break;
System.out.print(new String(tmp, 0, i));
}
if (channel.isClosed()) {
if (in.available() > 0) continue;
System.out.println("exit-status: " + channel.getExitStatus());
if(channel.getExitStatus()!=0){
return false;
}
break;
}
// try {
// Thread.sleep(1000);
// } catch (Exception ee) {
// }
}
channel.disconnect();
session.disconnect();
System.out.println("Linux指令執行結束");
return true;
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSchException e) {
e.printStackTrace();
} finally {// 最后流和连接的关闭
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("finally結束");
}
return true;
}
}