欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java JSch遠程執(zhí)行Shell命令的方法

 更新時間:2022年02月24日 11:45:53   作者:qhh0205  
本文主要介紹了Java JSch遠程執(zhí)行Shell命令,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

背景

項目需求,需要遠程 ssh 登錄到某個節(jié)點執(zhí)行 shell 命令來完成任務。對于這種需求,如果不用 java 程序,直接 linux 的 ssh 命令就可以完成,但是在編碼到程序中時需要相關的程序包來完成,本文主要介紹在 java 中如何使用 JSch 包實現(xiàn) ssh 遠程連接并執(zhí)行命令。

JSch 簡介

JSch 是Java Secure Channel的縮寫。JSch是一個SSH2的純Java實現(xiàn)。它允許你連接到一個SSH服務器,并且可以使用端口轉發(fā),X11轉發(fā),文件傳輸等,當然你也可以集成它的功能到你自己的應用程序??蚣躩sch很老的框架,更新到2016年,現(xiàn)在也不更新了。

JSch 使用 shell 執(zhí)行命令,有兩種方法

  • ChannelExec: 一次執(zhí)行一條命令,一般我們用這個就夠了。
  • ChannelShell: 可執(zhí)行多條命令,平時開發(fā)用的不多,根據需要來吧;
ChannelExec channelExec = (ChannelExec) session.openChannel("exec");//只能執(zhí)行一條指令(也可執(zhí)行符合指令)
ChannelShell channelShell = (ChannelShell) session.openChannel("shell");//可執(zhí)行多條指令 不過需要輸入輸出流

1. ChannelExec

每個命令之間用 ; 隔開。說明:各命令的執(zhí)行給果,不會影響其它命令的執(zhí)行。換句話說,各個命令都會執(zhí)行,但不保證每個命令都執(zhí)行成功。
每個命令之間用 && 隔開。說明:若前面的命令執(zhí)行成功,才會去執(zhí)行后面的命令。這樣可以保證所有的命令執(zhí)行完畢后,執(zhí)行過程都是成功的。
每個命令之間用 || 隔開。說明:|| 是或的意思,只有前面的命令執(zhí)行失敗后才去執(zhí)行下一條命令,直到執(zhí)行成功一條命令為止。

2. ChannelShell

對于ChannelShell,以輸入流的形式,可執(zhí)行多條指令,這就像在本地計算機上使用交互式shell(它通常用于:交互式使用)。如要要想停止,有兩種方式:

發(fā)送一個exit命令,告訴程序本次交互結束;
使用字節(jié)流中的available方法,來獲取數據的總大小,然后循環(huán)去讀。

使用示例

1. 引入 pom 依賴

<dependency>
? ?<groupId>com.jcraft</groupId>
? ?<artifactId>jsch</artifactId>
? ?<version>0.1.53</version>
</dependency>

2. jsch 使用示例

在此封裝了一個 Shell 工具類,用來執(zhí)行 shell 命令,具體使用細節(jié)在代碼注釋中有說明,可以直接拷貝并使用,代碼如下:

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 方式執(zhí)行 shell 命令
? ? ? ? ? ? channelExec = (ChannelExec) session.openChannel("exec");
? ? ? ? ? ? channelExec.setCommand(cmd);
? ? ? ? ? ? channelExec.connect(); ?// 執(zhí)行命令

? ? ? ? ? ? // 3. 獲取標準輸入流
? ? ? ? ? ? inputStreamReader = new BufferedReader(new InputStreamReader(channelExec.getInputStream()));
? ? ? ? ? ? // 4. 獲取標準錯誤輸入流
? ? ? ? ? ? errInputStreamReader = new BufferedReader(new InputStreamReader(channelExec.getErrStream()));

? ? ? ? ? ? // 5. 記錄命令執(zhí)行 log
? ? ? ? ? ? String line = null;
? ? ? ? ? ? while ((line = inputStreamReader.readLine()) != null) {
? ? ? ? ? ? ? ? runLog.append(line).append("\n");
? ? ? ? ? ? }

? ? ? ? ? ? // 6. 記錄命令執(zhí)行錯誤 log
? ? ? ? ? ? String errLine = null;
? ? ? ? ? ? while ((errLine = errInputStreamReader.readLine()) != null) {
? ? ? ? ? ? ? ? errLog.append(errLine).append("\n");
? ? ? ? ? ? }

? ? ? ? ? ? // 7. 輸出 shell 命令執(zhí)行日志
? ? ? ? ? ? System.out.println("exitStatus=" + channelExec.getExitStatus() + ", openChannel.isClosed="
? ? ? ? ? ? ? ? ? ? + channelExec.isClosed());
? ? ? ? ? ? System.out.println("命令執(zhí)行完成,執(zhí)行日志如下:");
? ? ? ? ? ? System.out.println(runLog.toString());
? ? ? ? ? ? System.out.println("命令執(zhí)行完成,執(zhí)行錯誤日志如下:");
? ? ? ? ? ? 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);
? ? }
}

需要注意的點

如果需要后臺執(zhí)行某個命令,不能直接 <命令> + & 的方式執(zhí)行,這樣在 JSch 中不生效,需要寫成這樣的格式:<命令> > /dev/null 2>&1 &。比如要后臺執(zhí)行 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遠程執(zhí)行Shell命令的方法的文章就介紹到這了,更多相關Java JSch遠程執(zhí)行Shell命令內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • SpringBoot使用AOP實現(xiàn)防重復提交功能

    SpringBoot使用AOP實現(xiàn)防重復提交功能

    這篇文章主要為大家詳細介紹了SpringBoot如何使用AOP實現(xiàn)防重復提交功能,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2024-03-03
  • Java使用HashMap實現(xiàn)并查集

    Java使用HashMap實現(xiàn)并查集

    這篇文章主要為大家詳細介紹了Java使用HashMap實現(xiàn)并查集,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • java單點登錄(SSO)的實現(xiàn)

    java單點登錄(SSO)的實現(xiàn)

    SSO是指在多個應用系統(tǒng)中個,用戶只需要登陸一次就可以訪問所有相互信任的應用系統(tǒng),本文主要介紹了java單點登錄的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2021-07-07
  • Java實現(xiàn)導出Excel功能

    Java實現(xiàn)導出Excel功能

    通過java中Controller層,來接受請求,數據庫查詢到的數據進行封裝,然后使用ExcelUtils進行輸出,接下來通過本文給大家分享Java實現(xiàn)導出Excel功能的實例代碼,感興趣的朋友跟隨小編一起看看吧
    2021-11-11
  • 關于JWT與cookie和token的區(qū)別說明

    關于JWT與cookie和token的區(qū)別說明

    這篇文章主要介紹了JWT與cookie和token的區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java編程通過list接口實現(xiàn)數據的增刪改查代碼示例

    Java編程通過list接口實現(xiàn)數據的增刪改查代碼示例

    這篇文章是介紹Java編程基礎方面的內容,涉及l(fā)ist接口的操作,通過list接口實現(xiàn)對數據的增刪改查的相關代碼,具有一定參考價值,需要的朋友可以了解下。
    2017-10-10
  • spring boot中多線程開發(fā)的注意事項總結

    spring boot中多線程開發(fā)的注意事項總結

    spring boot 通過任務執(zhí)行器 taskexecutor 來實現(xiàn)多線程和并發(fā)編程。下面這篇文章主要給大家介紹了關于spring boot中多線程開發(fā)的注意事項,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2018-09-09
  • Java上傳文件進度條的實現(xiàn)方法(附demo源碼下載)

    Java上傳文件進度條的實現(xiàn)方法(附demo源碼下載)

    這篇文章主要介紹了Java上傳文件進度條的實現(xiàn)方法,可簡單實現(xiàn)顯示文件上傳比特數及進度的功能,并附帶demo源碼供讀者下載參考,需要的朋友可以參考下
    2015-12-12
  • Java中SimpleDateFormat 格式化日期的使用

    Java中SimpleDateFormat 格式化日期的使用

    本文主要介紹了Java中SimpleDateFormat 格式化日期的使用,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • JMS 之 Active MQ 的消息傳輸(詳解)

    JMS 之 Active MQ 的消息傳輸(詳解)

    下面小編就為大家?guī)硪黄狫MS 之 Active MQ 的消息傳輸(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06

最新評論