Java 執行Shell腳本指令


一、介紹

有時候我們在Linux中運行Java程序時,需要調用一些Shell命令和腳本。而Runtime.getRuntime().exec()方法給我們提供了這個功能,而且Runtime.getRuntime()給我們提供了以下幾種exec()方法:

Process exec(String command)   
在單獨的進程中執行指定的字符串命令。   
  
Process exec(String[] cmdarray)   
在單獨的進程中執行指定命令和變量。   
  
Process exec(String[] cmdarray, String[] envp)   
在指定環境的獨立進程中執行指定命令和變量。   
  
Process exec(String[] cmdarray, String[] envp, File dir)   
在指定環境和工作目錄的獨立進程中執行指定的命令和變量。   
  
Process exec(String command, String[] envp)   
在指定環境的單獨進程中執行指定的字符串命令。   
  
Process exec(String command, String[] envp, File dir)   
在有指定環境和工作目錄的獨立進程中執行指定的字符串命令。

其中,其實cmdarray和command差不多,同時如果參數中如果沒有envp參數或設為null,表示調用命令將在當前程序執行的環境中執行;如果沒有dir參數或設為null,表示調用命令將在當前程序執行的目錄中執行,因此調用到其他目錄中的文件和腳本最好使用絕對路徑。各個參數的含義:

  1. cmdarray: 包含所調用命令及其參數的數組。 
  2. command: 一條指定的系統命令。
  3. envp: 字符串數組,其中每個元素的環境變量的設置格式為name=value;如果子進程應該繼承當前進程的環境,則該參數為 null。
  4. dir: 子進程的工作目錄;如果子進程應該繼承當前進程的工作目錄,則該參數為 null。

細心的讀者會發現,為了執行調用操作,JVM會啟一個Process,所以我們可以通過調用Process類的以下方法,得知調用操作是否正確執行:

abstract  int waitFor()   
導致當前線程等待,如有必要,一直要等到由該 Process 對象表示的進程已經終止。

 

二、調用Shell腳本

 

1、獲取鍵盤輸入

BufferedReader reader = null;
        try{
            reader = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("請輸入IP:");
            String ip = reader.readLine();

上述指令基本很常見:

1、創建讀入器:BufferReader

2、將數據流載入BufferReader,即InputStreamReader

3、將系統輸入載入InputStreamReader中

4、然后利用reader獲取數據。

2、構建指令

shell運行腳本指令為 sh **.sh args,其實這個格式與java格式相同。

我的腳本為:

#!/bin/sh
#根據進程名殺死進程
echo "This is a $call"
if [ $# -lt 2 ]
then
   echo "缺少參數:procedure_name和ip"
   exit 1
fi

echo "Kill the $1 process"
PROCESS=`ps -ef|grep $1|grep $2|grep -v grep|grep -v PPID|awk '{ print $2}'`
for i in $PROCESS
do
   echo "Kill the $1 process [ $i ]" 
done

其實所有准備若當,就是無法讀取里面的數據,執行shell指令,原因就是:

注意事項:

1.shell腳本必須有執行權限,比如部署后chmod -R 777 /webapps

2.shell文件,必須是UNIX格式,ANSI編碼格式,否則容易出問題(可以用notepad++,編輯->文檔格式轉換,格式->轉為ANSI格式(UNIX格式)

3、java程序

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

/**
 * @author :dongbl
 * @version :
 * @Description:
 * @date :9:19 2017/11/14
 */
public class TestBash {
    public static void main(String [] args){
        BufferedReader reader = null;
        try{
            reader = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("請輸入IP:");
            String ip = reader.readLine();
            String bashCommand = "sh "+ "/usr/local/java/jdk1.8.0_121/lib/stopffmpeg.sh" + " ffmpeg " + ip;
//            String bashCommand = "chmod 777 " + "/usr/local/java/jdk1.8.0_121/lib/stopffmpeg.sh" ;
//            String bashCommand = "kill -9" + ip;
            System.out.println(bashCommand);
            Runtime runtime = Runtime.getRuntime();
            Process pro = runtime.exec(bashCommand);
            int status = pro.waitFor();
            if (status != 0)
            {
                System.out.println("Failed to call shell's command ");
            }

            BufferedReader br = new BufferedReader(new InputStreamReader(pro.getInputStream()));
            StringBuffer strbr = new StringBuffer();
            String line;            
            while ((line = br.readLine())!= null)
            {                
                strbr.append(line).append("\n");
            }

            String result = strbr.toString();
            System.out.println(result);

        }
        catch (IOException ec)
        {
            ec.printStackTrace();
        }
        catch (InterruptedException ex){
            ex.printStackTrace();

        }
    }
}

其中文件路徑為絕對路徑,這點需要注意。

三、調試心得

在調試shell腳本執行過程中,反了幾個錯

1、構建指令不對

1、開始指令為:

 String bashCommand = "/usr/local/java/jdk1.8.0_121/lib/stopffmpeg.sh "+ " ffmpeg " + ip;
程序報錯,權限不足。
2、此時修改為:
String bashCommand = "chmod 777 "+"/usr/local/java/jdk1.8.0_121/lib/stopffmpeg.sh "+ " ffmpeg " + ip;

記住一定注意空格(格式)但此時依然無法指定腳本指令。3、在發現格式不對后,修改后,還是不行,此時指令為:

String bashCommand = "sh "+ "/usr/local/java/jdk1.8.0_121/lib/stopffmpeg.sh" + " ffmpeg " + ip;
 
        

2、文件格式不對

這是無法讀取內容的關鍵原因,因為sh文件是在Windows系統下生成的,所以需要將格式修改為linux格式的,即(UNIX格式)

此時網上程序可以了,然后看到指令不同,修改指令即可以了。

最后終於調通了,看來格式經驗不足啊

 

四、參考文獻

1、java調用shell腳本並傳遞參數

2、JAVA調用Shell腳本

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM