參考文檔:
maven jar包:https://mvnrepository.com/artifact/ch.ethz.ganymed/ganymed-ssh2
Ganymed SSH2 API文檔 :http://www.ganymed.ethz.ch/ssh2/javadoc/overview-summary.html
Java的Ganymed SSH2是一個在純Java中實現SSH-2協議的庫(在J2SE 1.4.2和5.0上測試過)。
它允許從Java程序中連接到SSH服務器。
它支持SSH會話(遠程命令執行和shell訪問)、本地和遠程端口轉發、本地流轉發、X11轉發、SCP和SFTP。
不依賴于任何JCE提供程序,因為所有加密功能都包含在內。
API簡介
一、API中常用的幾個類
Connection:創建服務器連接以及認證(用戶名密碼認證、秘鑰認證等)
Session :會話
SCPClient:可用于文件在不同服務器之間復制。在服務器端,路徑必須存在,如果不存在會報錯。
線程安全的——您可以同時下載(和上傳)不同的文件集,沒有任何問題。
SCPClient實際上是將每個請求映射到不同的會話。
SFTPv3Client: 執條單個指令(推薦使用) 提供了很多方法
二、使用步驟
1、creates a Connection object.
2、calls the connect() method.
3、calls some of the authentication methods (e.g., authenticateWithPublicKey()).
4、calls one or several times the openSession() method.
三、需要注意
1、認證成功后,當前目錄就位于/home/username/目錄之下,
你可以指定腳本文件所在的絕對路徑,或者通過cd導航到腳本文件所在的目錄,
然后傳遞執行腳本所需要的參數,完成腳本調用執行。
2、執行腳本以后,可以獲取腳本執行的結果文本,需要對這些文本進行正確編碼后返回給客戶端,避免亂碼產生
3、如果你需要執行多個linux控制臺腳本,比如第一個腳本的返回結果是第二個腳本的入參,你必須打開多個Session,也就是多次調用Session sess = conn.openSession();,使用完畢記得關閉就可以了
四、代碼
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import org.apache.log4j.Logger;
import com.viewhigh.vadp.framework.data.util.StringUtils;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.SCPClient;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
/**
*
* 描述:連接linux服務器并執行相關的shell命令
* 作者:cuicx
* 版本:V1.0
* 創建日期:2018年7月4日
* 修改日期: 2018年7月4日
*/
public class ConnectLinuxCommand {
private static final Logger logger = Logger.getLogger(ConnectLinuxCommand.class);
private static String DEFAULTCHARTSET = "UTF-8";
private static Connection conn;
/**
*
* @Title: login
* @Description: 用戶名密碼方式 遠程登錄linux服務器
* @return: Boolean
* @throws
*/
public static Boolean login(RemoteConnect remoteConnect) {
boolean flag = false;
try {
conn = new Connection(remoteConnect.getIp());
conn.connect();// 連接
flag = conn.authenticateWithPassword(remoteConnect.getUserName(), remoteConnect.getPassword());// 認證
if (flag) {
logger.info("認證成功!");
} else {
logger.info("認證失敗!");
conn.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return flag;
}
/**
*
* @Title: loginByKey
* @Description: 秘鑰方式 遠程登錄linux服務器
* @param remoteConnect
* @param keyFile 一個文件對象指向一個文件,該文件包含OpenSSH密鑰格式的用戶的DSA或RSA私鑰(PEM,不能丟失"-----BEGIN DSA PRIVATE KEY-----" or "-----BEGIN RSA PRIVATE KEY-----"標簽
* @param keyfilePass 如果秘鑰文件加密 需要用該參數解密,如果沒有加密可以為null
* @return Boolean
* @throws
*/
public static Boolean loginByFileKey(RemoteConnect remoteConnect, File keyFile, String keyfilePass) {
boolean flag = false;
// 輸入密鑰所在路徑
// File keyfile = new File("C:\\temp\\private");
try {
conn = new Connection(remoteConnect.getIp());
conn.connect();
// 登錄認證
flag = conn.authenticateWithPublicKey(remoteConnect.getUserName(), keyFile, keyfilePass);
if (flag) {
logger.info("認證成功!");
} else {
logger.info("認證失敗!");
conn.close();
}
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
/**
*
* @Title: loginByCharsKey
* @Description: 秘鑰方式 遠程登錄linux服務器
* @param remoteConnect
* @param keys 一個字符[],其中包含用戶的DSA或RSA私鑰(OpenSSH密匙格式,您不能丟失“----- begin DSA私鑰-----”或“-----BEGIN RSA PRIVATE KEY-----“標簽。char數組可以包含換行符/換行符。
* @param keyPass 如果秘鑰字符數組加密 需要用該字段解密 否則不需要可以為null
* @return Boolean
* @throws
*/
public static Boolean loginByCharsKey(RemoteConnect remoteConnect, char[] keys, String keyPass) {
boolean flag = false;
// 輸入密鑰所在路徑
// File keyfile = new File("C:\\temp\\private");
try {
conn = new Connection(remoteConnect.getIp());
conn.connect();
// 登錄認證
flag = conn.authenticateWithPublicKey(remoteConnect.getUserName(), keys, keyPass);
if (flag) {
logger.info("認證成功!");
} else {
logger.info("認證失敗!");
conn.close();
}
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
/**
*
* @Title: execute
* @Description: 遠程執行shll腳本或者命令
* @param cmd 腳本命令
* @return: result 命令執行完畢返回結果
* @throws
*/
public static String execute(String cmd){
String result = "";
try {
Session session = conn.openSession();// 打開一個會話
session.execCommand(cmd);// 執行命令
result = processStdout(session.getStdout(), DEFAULTCHARTSET);
// 如果為得到標準輸出為空,說明腳本執行出錯了
if (StringUtils.isBlank(result)) {
result = processStdout(session.getStderr(), DEFAULTCHARTSET);
}
conn.close();
session.close();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
/**
* @Title: executeSuccess
* @Description: 遠程執行shell腳本或者命令
* @param shell腳本或者命令
* @return String 命令執行成功后返回的結果值,如果命令執行失敗,返回空字符串,不是null
* @throws
*/
public static String executeSuccess(String cmd){
String result = "";
try {
Session session = conn.openSession();// 打開一個會話
session.execCommand(cmd);// 執行命令
result = processStdout(session.getStdout(), DEFAULTCHARTSET);
conn.close();
session.close();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
/**
*
* @Title: processStdout
* @Description: 解析腳本執行的返回結果
* @param in 輸入流對象
* @param charset 編碼
* @return String 以純文本的格式返回
* @throws
*/
public static String processStdout(InputStream in, String charset){
InputStream stdout = new StreamGobbler(in);
StringBuffer buffer = new StringBuffer();
try {
BufferedReader br = new BufferedReader(new InputStreamReader(stdout, charset));
String line = null;
while ((line = br.readLine()) != null) {
buffer.append(line + "\n");
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return buffer.toString();
}
/**
*
* @Title: ConnectLinux
* @Description: 通過用戶名和密碼關聯linux服務器
* @return
* @return String
* @throws
*/
public static boolean connectLinux(String ip,String userName,String password,String commandStr) {
logger.info("ConnectLinuxCommand scpGet===" + "ip:" + ip + " userName:" + userName + " commandStr:"
+ commandStr);
String returnStr = "";
boolean result = true;
RemoteConnect remoteConnect = new RemoteConnect();
remoteConnect.setIp(ip);
remoteConnect.setUserName(userName);
remoteConnect.setPassword(password);
try {
if (login(remoteConnect)) {
returnStr = execute(commandStr);
System.out.println(result);
}
} catch (Exception e) {
e.printStackTrace();
}
if (StringUtils.isBlank(returnStr)) {
result = false;
}
return result;
}
/**
*
* @Title: scpGet
* @Description: 從其他服務器獲取文件到本服務器指定目錄
* @param host ip(其他服務器)
* @param username 用戶名(其他服務器)
* @param password 密碼(其他服務器)
* @param remoteFile 文件位置(其他服務器)
* @param localDir 本服務器目錄
* @throws IOException
* @return void
* @throws
*/
public static void scpGet(String ip, String userName, String password, String remoteFile, String localDir)
throws IOException {
logger.info("ConnectLinuxCommand scpGet===" + "ip:" + ip + " userName:" + userName + " remoteFile:"
+ remoteFile + " localDir:" + localDir);
RemoteConnect remoteConnect = new RemoteConnect();
remoteConnect.setIp(ip);
remoteConnect.setUserName(userName);
remoteConnect.setPassword(password);
if (login(remoteConnect)) {
SCPClient client = new SCPClient(conn);
client.get(remoteFile, localDir);
conn.close();
}
}
/**
*
* @Title: scpPut
* @Description: 將文件復制到其他計算機中
* @param host
* @param username
* @param password
* @param localFile
* @param remoteDir
* @throws IOException
* @return void
* @throws
*/
public static void scpPut(String ip, String userName, String password, String localFile, String remoteDir)
throws IOException {
logger.info("ConnectLinuxCommand scpPut===" + "ip:" + ip + " userName:" + userName + " localFile:"
+ localFile + " remoteDir:" + remoteDir);
RemoteConnect remoteConnect = new RemoteConnect();
remoteConnect.setIp(ip);
remoteConnect.setUserName(userName);
remoteConnect.setPassword(password);
if (login(remoteConnect)) {
SCPClient client = new SCPClient(conn);
client.put(localFile, remoteDir);
conn.close();
}
}
}
public class RemoteConnect {
private String ip;
private String userName;
private String password;
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
public class CcxTest {
@Test
public void testDemo() {
//cd /home/ubuntu/Desktop/music_rec/user_sim/result;cat xyy_result_m10d.json
//String commandStr="cd /home;rm -rf aa.txt";
String commandStr="cd /home;cat aa.txt;rm -rf aa.txt";
Boolean result=ConnectLinuxCommand.connectLinux("192.168.0.11","root","123456",commandStr);
System.out.println(result);
}
@Test
public void testDemo2() throws IOException {
try {
ConnectLinuxCommand.scpGet("192.168.0.11","root","123456", "test.txt", "/home/");
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void testDemo3() {
try {
ConnectLinuxCommand.scpPut("192.168.0.11","root","123456", "test.txt", "/home/");
} catch (Exception e) {
e.printStackTrace();
}
}
}