一、Java调用Linux系统的命令非常简单

这是一个非常常用的调用方法示例:

public String executeLinuxCmd(String cmd) {
        System.out.println("got cmd job : " + cmd);
        Runtime run = Runtime.getRuntime();
        try {
            Process process = run.exec(cmd);
            InputStream in = process.getInputStream();
            BufferedReader bs = new BufferedReader(new InputStreamReader(in));
            // System.out.println("[check] now size \n"+bs.readLine());
         StringBuffer out = new StringBuffer();
         byte[] b = new byte[8192];
         for (int n; (n = in.read(b)) != -1;) {
           out.append(new String(b, 0, n));
          }
          System.out.println("job result [" + out.toString() + "]");
            in.close();
            // process.waitFor();
            process.destroy();
            return result;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

二、含有管道符(|)多级命令串联查询

public List<String> executeLinuxCmd(String cmd) {
        System.out.println("got cmd job : " + cmd);
        Runtime run = Runtime.getRuntime();
        try {
//            Process process = run.exec(cmd);
            Process process = run.exec(new String[] {"/bin/sh", "-c", cmd});
            InputStream in = process.getInputStream();
            BufferedReader bs = new BufferedReader(new InputStreamReader(in));
            List<String> list = new ArrayList<String>();
            String result = null;
            while ((result = bs.readLine()) != null) {
                System.out.println("job result [" + result + "]");
                list.add(result);
            }
            in.close();
            // process.waitFor();
            process.destroy();
            return list;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

三、含有cd操作的方法示例

  1. 问题背景

1.1 java程序运行在/home/lings目录下;

1.2 希望删除/home/test目录下的文件proxy.log;

1.3 调用上面的接口两次?

executeLinuxCmd("cd /home/test");
executeLinuxCmd("rm -fr /home/proxy.log");

是不行的!

1.4 这个接口的调用是单次事务型的,就是每次调用都是独立的事务或者说操作,没有关联的。

那这种“复杂”一点的操作流程怎么办呢?

1.5 方法a: 可以写一个独立的脚本,然后一次运行脚本,这样多复杂的逻辑都没问题。

1.6 方法b: 可以启动一个shell长连接,保持连接,发送多条命令,最后释放连接。

示例逻辑代码:

public void executeNewFlow() {
        Runtime run = Runtime.getRuntime();
        File wd = new File("/bin");
        System.out.println(wd);
        Process proc = null;
        try {
            proc = run.exec("/bin/bash", null, wd);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (proc != null) {
            BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true);
            out.println("cd /home/test");
            out.println("pwd");
            out.println("rm -fr /home/proxy.log");
            out.println("exit");//这个命令必须执行,否则in流不结束。
            try {
                String line;
                while ((line = in.readLine()) != null) {
                    System.out.println(line);
                }
                proc.waitFor();
                in.close();
                out.close();
                proc.destroy();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

三的优化和演进(返回值)

public List<String> executeNewFlow(List<String> commands) {
       List<String> rspList = new ArrayList<String>();
       Runtime run = Runtime.getRuntime();
       try {
           Process proc = run.exec("/bin/bash", null, null);
           BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
           PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true);
           for (String line : commands) {
               out.println(line);
           }
           // out.println("cd /home/test");
           // out.println("pwd");
           // out.println("rm -fr /home/proxy.log");
           out.println("exit");// 这个命令必须执行,否则in流不结束。
           String rspLine = "";
           while ((rspLine = in.readLine()) != null) {
               System.out.println(rspLine);
               rspList.add(rspLine);
           }
           proc.waitFor();
           in.close();
           out.close();
           proc.destroy();
       } catch (IOException e1) {
           e1.printStackTrace();
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       return rspList;
   }