java执行shell脚本无权限(执行shell脚本无权限讲解) -九游会ag


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 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 strlist = new arraylist(); 
        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是不是明智的呢?

九游会ag的版权声明

派优网部分新闻资讯、展示的图片素材等内容均为用户自发上传(部分报媒/平媒内容转载自网络合作媒体),仅供学习交流。用户通过本站上传、发布任何内容的知识产权归属用户或原始著作权人所有。如有侵犯您的九游会ag的版权,请联系九游会ag 一经核实,立即删除。并对发布账号进行封禁。


本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
搜索
网站地图