java执行shell脚本无权限(执行shell脚本无权限讲解)

java可以通过Runtime来调用其他进程,如cmd命令,shell文件或脚本等,接下来我们就来聊聊关于java执行shell脚本无权限?以下内容大家不妨参考一二希望能帮到您!

java执行shell脚本无权限(执行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.infosoftType=$(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是不是明智的呢?

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页