Java執行shell遇到的各種問題

來源:互聯網
上載者:User

1、判斷子進程是否執行結束

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

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

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

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

有的時候我們發現調用waitFor()方法後,java主線程會一直阻塞在waitFor()處,阻塞的原因是什麼呢。分析一下:

Java在執行Runtime.getRuntime().exec(jyName)之後,Linux會建立一個進程,該進程與JVM進程建立三個管道串連,標準輸入資料流、標準輸出資料流、標準錯誤流,假設linux進程不斷

向標準輸出資料流和標準錯誤流寫資料,而JVM卻不讀取,資料會暫存在linux緩衝區,當緩衝區存滿之後導致該進程無法繼續寫資料,會僵死,導致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", "軟體升級失敗:執行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;}

也可以在執行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;}@Overridepublic 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 blocke.printStackTrace();}}}};t1.start();t2.start();} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();} finally {}}}

3、shell指令碼中有關聯指令碼,注意路徑

就是shell指令碼中還要執行其他指令碼,這時候就是注意一個路徑的問題,這個問題也是我找了好長時間的一個問題。

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

在Test.java類調用了etc目錄下的a.sh指令碼, a.sh指令碼中執行etc目錄下的b.sh指令碼,原來我在a.sh指令碼中寫的是./b.sh。其實這樣linux是找不到b.sh的,因為我們執行是在

Test.class目錄下調用的/etc/a.sh  所以當a.sh中執行./b.sh的時候他會在Test.class目錄下尋找,所以找不到,所以a.sh中要寫成/etc/b.sh

4、java連續調用多個指令碼

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

就是這種數組的方式。


5、java執行.sh指令檔的時候直接寫目錄就行,例如這樣:Runtime.getRuntime().exec(“/etc/a.sh”)

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

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







相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.