執行shell腳本無許可權講解:java執行shell腳本無許可權

背景

java可以通過Runtime來調用其他進程,如cmd命令,shell文件或腳本等。

基本用法

Runtime執行時返回一個Process對象,利用該對象完成腳本執行。下面的例子中,Linux的/home/目錄下有一個刪除指定日期文件的腳本deletefile.sh,Java調用該腳本的方法如下。

 /**
     * 刪除指定日期的文件
     * @param date  yyyy-MM-dd格式
     */
    private static  void setSystemDate(String date){
        Process process = null;
        String command1 = "/bin/sh /home/deletefile.sh "+date;
        System.out.println(command1);
        try {
            process = Runtime.getRuntime().exec(command1);
            //必須等待該進程結束,否則時間設置就無法生效
            process.waitFor();
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }finally{
            if(process!=null){
                process.destroy();
            }
        }
    }

緩衝區滿問題

如果腳本執行過程中產生大量的控制台輸出信息,這種信息會被Shell進程輸出到內存緩衝區中,而上述用法中作為父進程的java進程並沒有處理緩衝區內容,那麼就會出現緩衝區滿,Java進程掛起的情況。
解決辦法是,使用Java線程讀取Shell腳本的輸出信息。

   public static List<String> executeShell(String shpath, String var){
        
        //String shpath="/test/test.sh";   // sh 路徑
        //String var="201102";             // sh 參數
        String shellVar = (var==null)?"":var;
        String command1 = "chmod 777 " + shpath; // 為 sh 添加許可權
        String command2 = "/bin/sh " + shpath + " " + shellVar; 
        final List<String> strList = new ArrayList<String>(); 
        Process process1 = null;
        BufferedReader in = null;
        try {
            process1 = Runtime.getRuntime().exec(command1); // 執行添加許可權的命令
            process1.waitFor(); // 如果執行多個命令,必須加上
            final Process process2 = Runtime.getRuntime().exec(command2);
           
            //處理InputStream的線程  
            new Thread() {  
                @Override  
                public void run() {  
                    BufferedReader in = new BufferedReader(new InputStreamReader(process2.getInputStream()));   
                    String line = null;  
                    try{  
                        while((line = in.readLine()) != null) {  
                        	strList.add(line);
                        }  
                    }catch(IOException e) {                         
                        e.printStackTrace();  
                    }finally {  
                        try {  
                            in.close();  
                        }   
                        catch (IOException e) {  
                            e.printStackTrace();  
                        }  
                    }  
                }  
            }.start();  

            //處理ErrorStream的線程  
            new Thread() {  
                @Override  
                public void run(){  
                    BufferedReader err = new BufferedReader(new InputStreamReader(process2.getErrorStream()));   
                    String line = null;  
                    try{  
                        while((line = err.readLine()) != null)  
                        {  
                        	strList.add(line); 
                        }  
                    }catch(IOException e){                         
                        e.printStackTrace();  
                    }finally{  
                        try{  
                            err.close();  
                        }catch (IOException e){  
                            e.printStackTrace();  
                        }  
                    }  
                }  
            }.start(); 
            
            process2.waitFor();
 
        } catch (IOException e) {

        } catch (InterruptedException e) {
           
        }finally {
            if(in != null){
                try {
                    in.close();
                } catch (IOException e) {
 
                }
            }
            if(process1 != null){
                process1.destroy();
            }
        }
        return strList;
    }

線程阻塞問題

如果執行的shell腳本中有等待輸入命令,比如more操作,那麼在使用java進程讀取緩衝區內容的時候,會出現線程阻塞等待的問題。
例如,下面的腳本讀取文件內容。

filePath=/home/software.info
softType=$(more $filePath)
echo $softType

上述三行代碼很簡單地輸出了一個文件的內容,而且這個文件很短,只有一行,在Linux下執行沒有問題,但是如果用Java調用executeShell方法執行的話,處理InputStream的線程會出現阻塞等待問題,根源在於腳本中的more命令,它會等待控制台的輸入,從而導致了Java進程的阻塞。
解決辦法就是避免在shell腳本中使用more命令,用cat命令替換即可。

管道命令不執行問題

使用Process執行shell命令時,如果命令中包含管道命令,直接執行會得不到正確結果,解決辦法是使用/bin/sh,將/bin/sh放在待執行的shell命令的前面,可保證管道命令的正確執行。

String command1 = "/bin/sh ifconfig | grep if= | awk '{print $1,$6}'";

啟示錄

究竟在Java中調用Shell是不是明智的呢?

原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/220752.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
投稿專員的頭像投稿專員
上一篇 2024-12-09 12:17
下一篇 2024-12-09 12:17

相關推薦

發表回復

登錄後才能評論