<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
專案需求,需要遠端 ssh 登入到某個節點執行 shell 命令來完成任務。對於這種需求,如果不用 java 程式,直接 linux 的 ssh 命令就可以完成,但是在編碼到程式中時需要相關的程式包來完成,本文主要介紹在 java 中如何使用 JSch 包實現 ssh 遠端連線並執行命令。
JSch 是Java Secure Channel的縮寫。JSch是一個SSH2的純Java實現。它允許你連線到一個SSH伺服器,並且可以使用埠轉發,X11轉發,檔案傳輸等,當然你也可以整合它的功能到你自己的應用程式。框架jsch很老的框架,更新到2016年,現在也不更新了。
JSch 使用 shell 執行命令,有兩種方法
ChannelExec channelExec = (ChannelExec) session.openChannel("exec");//只能執行一條指令(也可執行符合指令) ChannelShell channelShell = (ChannelShell) session.openChannel("shell");//可執行多條指令 不過需要輸入輸出流
1. ChannelExec
每個命令之間用 ; 隔開。說明:各命令的執行給果,不會影響其它命令的執行。換句話說,各個命令都會執行,但不保證每個命令都執行成功。
每個命令之間用 && 隔開。說明:若前面的命令執行成功,才會去執行後面的命令。這樣可以保證所有的命令執行完畢後,執行過程都是成功的。
每個命令之間用 || 隔開。說明:|| 是或的意思,只有前面的命令執行失敗後才去執行下一條命令,直到執行成功一條命令為止。
2. ChannelShell
對於ChannelShell,以輸入流的形式,可執行多條指令,這就像在本地計算機上使用互動式shell(它通常用於:互動式使用)。如要要想停止,有兩種方式:
傳送一個exit命令,告訴程式本次互動結束;
使用位元組流中的available方法,來獲取資料的總大小,然後迴圈去讀。
1. 引入 pom 依賴
<dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.53</version> </dependency>
2. jsch 使用範例
在此封裝了一個 Shell 工具類,用來執行 shell 命令,具體使用細節在程式碼註釋中有說明,可以直接拷貝並使用,程式碼如下:
package org.example.shell; /** * Created by qianghaohao on 2021/3/28 */ import com.jcraft.jsch.ChannelExec; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /** * @description: * @author: qianghaohao * @time: 2021/3/28 */ public class Shell { private String host; private String username; private String password; private int port = 22; private int timeout = 60 * 60 * 1000; public Shell(String host, String username, String password, int port, int timeout) { this.host = host; this.username = username; this.password = password; this.port = port; this.timeout = timeout; } public Shell(String host, String username, String password) { this.host = host; this.username = username; this.password = password; } public String execCommand(String cmd) { JSch jSch = new JSch(); Session session = null; ChannelExec channelExec = null; BufferedReader inputStreamReader = null; BufferedReader errInputStreamReader = null; StringBuilder runLog = new StringBuilder(""); StringBuilder errLog = new StringBuilder(""); try { // 1. 獲取 ssh session session = jSch.getSession(username, host, port); session.setPassword(password); session.setTimeout(timeout); session.setConfig("StrictHostKeyChecking", "no"); session.connect(); // 獲取到 ssh session // 2. 通過 exec 方式執行 shell 命令 channelExec = (ChannelExec) session.openChannel("exec"); channelExec.setCommand(cmd); channelExec.connect(); // 執行命令 // 3. 獲取標準輸入流 inputStreamReader = new BufferedReader(new InputStreamReader(channelExec.getInputStream())); // 4. 獲取標準錯誤輸入流 errInputStreamReader = new BufferedReader(new InputStreamReader(channelExec.getErrStream())); // 5. 記錄命令執行 log String line = null; while ((line = inputStreamReader.readLine()) != null) { runLog.append(line).append("n"); } // 6. 記錄命令執行錯誤 log String errLine = null; while ((errLine = errInputStreamReader.readLine()) != null) { errLog.append(errLine).append("n"); } // 7. 輸出 shell 命令執行紀錄檔 System.out.println("exitStatus=" + channelExec.getExitStatus() + ", openChannel.isClosed=" + channelExec.isClosed()); System.out.println("命令執行完成,執行紀錄檔如下:"); System.out.println(runLog.toString()); System.out.println("命令執行完成,執行錯誤紀錄檔如下:"); System.out.println(errLog.toString()); } catch (Exception e) { e.printStackTrace(); } finally { try { if (inputStreamReader != null) { inputStreamReader.close(); } if (errInputStreamReader != null) { errInputStreamReader.close(); } if (channelExec != null) { channelExec.disconnect(); } if (session != null) { session.disconnect(); } } catch (IOException e) { e.printStackTrace(); } } return runLog.toString(); } }
上述工具類使用:
package org.example; import org.example.shell.Shell; /** * Hello world! * */ public class App { public static void main( String[] args ) { String cmd = "ls -1"; Shell shell = new Shell("192.168.10.10", "ubuntu", "11111"); String execLog = shell.execCommand(cmd); System.out.println(execLog); } }
如果需要後臺執行某個命令,不能直接 <命令> + & 的方式執行,這樣在 JSch 中不生效,需要寫成這樣的格式:<命令> > /dev/null 2>&1 &。比如要後臺執行 sleep 60,需要寫成 sleep 60 > /dev/null 2>&1
具體 issue 見這裡:https://stackoverflow.com/questions/37833683/running-programs-using-jsch-in-the-background
https://www.cnblogs.com/slankka/p/11988477.html
https://blog.csdn.net/sinat_24928447/article/details/83022818
到此這篇關於Java JSch遠端執行Shell命令的方法的文章就介紹到這了,更多相關Java JSch遠端執行Shell命令內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45