项目中有这样一个需求。web程序 调用脚本 来运行服务器上的程序 。执行任务。
想到了ssh 操作 程序的启动脚本,同时传递参数。
一位大佬的 工具类 不废话 直接分享
package util.ssh;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.SCPClient;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
import java.io.*;
/**
* ssh操作类
*
*/
public class RemoteExecuteCommand {
/**
* 字符编码默认是utf-8
*/
private static final String DEFAULT_CHART = "UTF-8";
/**
* 远程 IP
*/
private String ip;
/**
* 用户名
*/
private String userName;
/**
* 密码
*/
private String password;
public RemoteExecuteCommand(String ip, String userName, String password) {
this.ip = ip;
this.userName = userName;
this.password = password;
}
/**
* 获取 SSH 远程连接
*
* @return 远程连接
*/
public Connection getConnection() throws IOException {
Connection conn = new Connection(ip);
// 连接
conn.connect();
// 认证
boolean flag = conn.authenticateWithPassword(userName, password);
if(!flag) {
throw new IOException("ssh远程连接认证失败!");
}
return conn;
}
/**
* 执行指定的命令
*
* @param conn 远程连接
* @param cmd 指定的命令信息
* @return 执行的结果
*/
public String execute(Connection conn, String cmd) throws IOException {
String result;
Session session = null;
try {
// 打开一个会话
session = conn.openSession();
// 执行命令
session.execCommand(cmd);
result = processStdout(session.getStdout(), DEFAULT_CHART);
// 如果为得到标准输出为空,说明脚本执行出错了
if ("".equals(result)) {
result = processStdout(session.getStderr(), DEFAULT_CHART);
}
} finally {
if(session != null) {
session.close();
}
}
return result;
}
/**
* 将本地文件目录下所有的文件存储到远程机器指定的目录上
*
* @param conn 远程连接
* @param localPath 本地文件目录
* @param remotePath 远程文件目录
*/
public void scpFileDir(Connection conn, String localPath, String remotePath) throws IOException {
SCPClient client = new SCPClient(conn);
File file = new File(localPath);
File[] files = file.listFiles();
if(files == null) {
throw new IOException("the path no file!");
}
String[] localFiles = new String[files.length];
for (int i = 0, length = files.length; i < length; i++) {
localFiles[i] = files[i].getAbsolutePath();
}
client.put(localFiles, remotePath);
}
/**
* 将本地文件存储到远程机器指定的目录上
*
* @param conn 远程连接
* @param filePath 本地文件
* @param remotePath 远程文件目录
*/
public void scpFile(Connection conn, String filePath, String remotePath) throws IOException {
SCPClient client = new SCPClient(conn);
File file = new File(filePath);
if(file.isFile()) {
client.put(filePath, remotePath);
} else {
throw new IOException("the file not find!");
}
}
/**
* 解析脚本执行返回的结果集
* @param in 输入流对象
* @param charset 编码
* @return 流获取结果
*/
private String processStdout(InputStream in, String charset) throws IOException {
InputStream stdout = new StreamGobbler(in);
StringBuilder builder = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(stdout, charset));
String line;
while ((line = br.readLine()) != null) {
builder.append(line).append("\n");
}
return builder.toString();
}
public void close(Connection connection) {
if(connection != null) {
connection.close();
}
}
}
测试类
public static void main(String[] args) {
RemoteExecuteCommand command = new RemoteExecuteCommand("xxx", "xxx", "xxx");
Connection connection = null;
try {
//linux 本地机器
connection = command.getConnection();
String linux= command.execute(connection, "sh /home//mytest/test.sh a b");
System.out.println(linux);
//hadoop 集群
String hadoop = command.execute(connection, "hadoop fs -ls impala");
System.out.println(hadoop);
}catch (Exception e){
e.printStackTrace();
}
}