亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java中如何執(zhí)行多條shell/bat命令

 更新時間:2021年08月11日 08:41:35   作者:qq342643414  
這篇文章主要介紹了Java中如何執(zhí)行多條shell/bat命令的方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

java調用process執(zhí)行命令

public class ShellUtil {
    public static String runShell (String shStr) throws Exception {
        Process process;
        process = Runtime.getRuntime().exec( new String[]{ "/bin/sh" , "-c" ,shStr});
        process.waitFor();
        BufferedReader read = new BufferedReader( new InputStreamReader(process.getInputStream()));
        String line = null ;
        String result = "" ;
        while ((line = read.readLine())!= null ){
            result+=line;
        }
        return result;
    }
}

注意:如果是windows操作系統(tǒng)要改為

Runtime.getRuntime().exec(new String[]{"**cmd** exe","-c","command"});

1.當要執(zhí)行多條時且不依賴事務,可以分開多次調用

public class ExecuteShell {
    public static void main (String[] args){
        String command1 = "some command" ;
        String command2 = "some command" ;
        String message1 = ShellUtil.runShell(command1);
        String message2 = ShellUtil.runShell(command2);
        System. out .println(message1);
        System. out .println(message2);
    }
}

2.但是當命令之間有事務依賴時

比如一條命令是登錄數據庫,第二條執(zhí)行查詢語句,上面分開多次調用的方式就不行。需要做改動如下

public class ExecuteShell {
    public static void main (String[] args){
        String command1 = "some command" ;
        String command2 = "some command" ;
        String command = command1 + " && " + command2;
        String message = ShellUtil.runShell(command);
        System. out .println(message);
    }
}

Java執(zhí)行shell遇到的各種問題

1、判斷子進程是否執(zhí)行結束

有的時候我們用java調用shell之后,之后的操作要在Process子進程正常執(zhí)行結束的情況下才可以繼續(xù),所以我們需要判斷Process進程什么時候終止。

Process類提供了waitFor()方法。該方法導致當前線程等待,直到Process線程終止。

Process.waitFor()是有一個int類型返回值的,當返回值為0的時候表Process進程正常終止。否則一般是腳本執(zhí)行出錯了(我遇到的一般是這種情況)。

2、Process.waitFor()導致當前線程阻塞

有的時候我們發(fā)現(xiàn)調用waitFor()方法后,java主線程會一直阻塞在waitFor()處,阻塞的原因是什么呢?

分析一下:

Java在執(zhí)行Runtime.getRuntime().exec(jyName)之后,Linux會創(chuàng)建一個進程,該進程與JVM進程建立三個管道連接,標準輸入流、標準輸出流、標準錯誤流,假設linux進程不斷向標準輸出流和標準錯誤流寫數據,而JVM卻不讀取,數據會暫存在linux緩存區(qū),當緩存區(qū)存滿之后導致該進程無法繼續(xù)寫數據,會僵死,導致java進程會卡死在waitFor()處,永遠無法結束。

解決辦法:

java進程在waitFor()前不斷讀取標準輸出流和標準錯誤流:

 //jyName  解壓腳本路徑
  String fileName=fileList.get(0).toString().substring(fileList.get(0).toString().lastIndexOf(File.separator)+1);
  String  jyName="/etc/zxvf.sh "+fileName;
  try {
   Process p0 = Runtime.getRuntime().exec(jyName);
   //讀取標準輸出流
   BufferedReader bufferedReader =new BufferedReader(new InputStreamReader(p0.getInputStream()));
   String line;
   while ((line=bufferedReader.readLine()) != null) {
       System.out.println(line);
   } 
   //讀取標準錯誤流
   BufferedReader brError = new BufferedReader(new InputStreamReader(p0.getErrorStream(), "gb2312"));
   String errline = null;
   while ((errline = brError.readLine()) != null) {
     System.out.println(errline);
   }
   //waitFor()判斷Process進程是否終止,通過返回值判斷是否正常終止。0代表正常終止
   int c=p0.waitFor();
   if(c!=0){
    baseRes.put("desc", "軟件升級失敗:執(zhí)行zxvf.sh異常終止");
    baseRes.setReturnFlag(false);
    return baseRes;
   }
  } catch (IOException e1) {
   baseRes.put("desc", "軟件升級失?。何募鈮菏?);
   baseRes.setReturnFlag(false);
   return baseRes;
  } catch (InterruptedException e1) {
   baseRes.put("desc", "軟件升級失?。何募鈮菏?);
   baseRes.setReturnFlag(false);
   return baseRes;
  }

也可以在執(zhí)行Runtime.getRuntime().exec(jyName)之后另外再啟動兩個線程分別讀取標準錯誤流和標準輸出流

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader; 

public class ExcuteThread extends Thread {
 private String name; 
 public ExcuteThread(String name) {
  this.name = name;
 }
 @Override
 public void run() {
  try {
   Process p = Runtime.getRuntime().exec(name);
   InputStream fis = p.getInputStream();
   final BufferedReader brError = new BufferedReader(
     new InputStreamReader(p.getErrorStream(), "gb2312"));
   InputStreamReader isr = new InputStreamReader(fis, "gb2312");
   final BufferedReader br = new BufferedReader(isr);
   Thread t1 = new Thread() {
    public void run() {
     String line = null;
     try {
      while ((line = brError.readLine()) != null) {
       // System.out.println(line);
      }
     } catch (IOException e) {
      e.printStackTrace();
     } finally {
      try {
       if (brError != null)
        brError.close();
      } catch (IOException e) {
       e.printStackTrace();
      }
     }
    }
   };
   Thread t2 = new Thread() {
    public void run() {
     String line = null;
     try {
      while ((line = br.readLine()) != null) {
       // System.out.println(line);
      }
     } catch (IOException e) {
      e.printStackTrace();
     } finally {
      try {
       if (br != null)
        br.close();
      } catch (IOException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
      }
     }
    }
   };
   t1.start();
   t2.start();
 
  } catch (IOException e1) {
   // TODO Auto-generated catch block
   e1.printStackTrace();
  } finally {
  } 
 } 
}

3、shell腳本中有關聯(lián)腳本,注意路徑

就是shell腳本中還要執(zhí)行其他腳本,這時候就是注意一個路徑的問題,這個問題也是我找了好長時間的一個問題。

Process p=Runtime.getRuntime().exec(“/etc/a.sh”)

在Test.java類調用了etc目錄下的a.sh腳本, a.sh腳本中執(zhí)行etc目錄下的b.sh腳本,原來我在a.sh腳本中寫的是./b.sh。

其實這樣linux是找不到b.sh的,因為我們執(zhí)行是在Test.class目錄下調用的/etc/a.sh 所以當a.sh中執(zhí)行./b.sh的時候他會在Test.class目錄下尋找,所以找不到,所以a.sh中要寫成/etc/b.sh

4、java連續(xù)調用多個腳本

  String[] cmd = { "/bin/sh", "-c", "rm -rf /installation/upgrade/ ; mkdir /installation/upgrade/" };
  Process p = Runtime.getRuntime().exec(cmd);
  p.waitFor();

就是這種數組的方式。

5、java執(zhí)行.sh腳本文件的時候直接寫目錄就行

例如這樣:

Runtime.getRuntime().exec(“/etc/a.sh”)

java 直接執(zhí)行語句的時候需要加上"/bin/sh" 例如這樣:

   String name="/bin/sh cd /installation/upgrade/ip89_install_packet";
   Process p = Runtime.getRuntime().exec(name);

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • SpringBoot引入Thymeleaf的實現(xiàn)方法

    SpringBoot引入Thymeleaf的實現(xiàn)方法

    這篇文章主要介紹了SpringBoot引入Thymeleaf的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • Springcloud實現(xiàn)服務多版本控制的示例代碼

    Springcloud實現(xiàn)服務多版本控制的示例代碼

    這篇文章主要介紹了Springcloud實現(xiàn)服務多版本控制的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-05-05
  • Java基于虹軟實現(xiàn)人臉識別、人臉比對、活性檢測等

    Java基于虹軟實現(xiàn)人臉識別、人臉比對、活性檢測等

    本文主要介紹了Java基于虹軟實現(xiàn)人臉識別、人臉比對、活性檢測等,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • Java 數組詳解及示例代碼

    Java 數組詳解及示例代碼

    本文主要介紹Java 數組的知識,這里整理了數組所有操作方法,并一一列舉,有學習的朋友可以參考下
    2016-09-09
  • SpringBoot利用自定義注解實現(xiàn)隱私數據脫敏(加密顯示)的解決方案

    SpringBoot利用自定義注解實現(xiàn)隱私數據脫敏(加密顯示)的解決方案

    這兩天在整改等保測出的問題,里面有一個“用戶信息泄露”的風險項(就是后臺系統(tǒng)里用戶的一些隱私數據直接明文顯示了),其實指的就是要做數據脫敏,本文給大家介紹了SpringBoot利用自定義注解實現(xiàn)隱私數據脫敏(加密顯示)的解決方案,需要的朋友可以參考下
    2023-11-11
  • 如何解決SpringBoot2.x版本對Velocity模板不支持的方案

    如何解決SpringBoot2.x版本對Velocity模板不支持的方案

    這篇文章主要介紹了如何解決SpringBoot2.x版本對Velocity模板不支持的方案,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-12-12
  • 淺析java volatitle 多線程問題

    淺析java volatitle 多線程問題

    Volatile修飾的成員變量在每次被線程訪問時,都強迫從共享內存中重讀該成員變量的值。而且,當成員變量發(fā)生變化時,強迫線程將變化值回寫到共享內存
    2013-08-08
  • Mybatis調用SQL?Server存儲過程的實現(xiàn)示例

    Mybatis調用SQL?Server存儲過程的實現(xiàn)示例

    在軟件開發(fā)過程中,經常會使用到存儲過程,本文就來介紹一下Mybatis調用SQL?Server存儲過程的實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • 詳解Servlet之過濾器(Filter)

    詳解Servlet之過濾器(Filter)

    本篇文章主要介紹了Servlet——過濾器(Filter),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • 總結一些Java常用的加密算法

    總結一些Java常用的加密算法

    今天給大家?guī)淼氖顷P于Java的相關知識,文章圍繞著Java加密算法展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06

最新評論