# Windows
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import java.io.*;import java.nio.charset.Charset;public class exec { public static void main (String[] args) { Process process = null ; try { String cmd = "cmd /c echo 1 > 1.txt" ; process = Runtime.getRuntime().exec(cmd); BufferedReader br = new BufferedReader (new InputStreamReader (process.getInputStream(), Charset.forName("gbk" ))); String line = null ; while ((line = br.readLine()) != null ) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); } } }
对执行的 command 判断,非空后进行识别
其中 StringTokenizer
默认是空格分隔
再存入数组
一直到 exec 返回值
来看下这三个值的含义
会发现,其实底层还是使用 ProcessBuilder.start
来执行刚才拿到的 cmdarray
数组的第一个元素存入 prog
,也就是要执行的命令
然后判断 security
是否为空,是则继续进行,否则调用 SecurityManager.checkExec
检验 prog
执行的命令不能是空格开头,否则会抛出异常
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 public Process start () throws IOException { String[] cmdarray = command.toArray(new String [command.size()]); cmdarray = cmdarray.clone(); for (String arg : cmdarray) if (arg == null ) throw new NullPointerException (); String prog = cmdarray[0 ]; SecurityManager security = System.getSecurityManager(); if (security != null ) security.checkExec(prog); String dir = directory == null ? null : directory.toString(); for (int i = 1 ; i < cmdarray.length; i++) { if (cmdarray[i].indexOf('\u0000' ) >= 0 ) { throw new IOException ("invalid null character in command" ); } } try { return ProcessImpl.start(cmdarray, environment, dir, redirects, redirectErrorStream); } catch (IOException | IllegalArgumentException e) { String exceptionInfo = ": " + e.getMessage(); Throwable cause = e; if ((e instanceof IOException) && security != null ) { try { security.checkRead(prog); } catch (SecurityException se) { exceptionInfo = "" ; cause = se; } } throw new IOException ( "Cannot run program \"" + prog + "\"" + (dir == null ? "" : " (in directory \"" + dir + "\")" ) + exceptionInfo, cause); } }
在执行的命令前加上 cmd /c
实际上是告诉计算机此时的环境变量
# Linux
ProcessBuilder
下的构造方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public ProcessBuilder (String... command) { this .command = new ArrayList <>(command.length); for (String arg : command) this .command.add(arg); }
如果传入参数是字符串数组,参数不会被 StringTokenizer
影响
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package exec;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.nio.charset.Charset;public class RuntimeExec { public static void main (String[] args) { Process process = null ; try { String[] cmd = {"/bin/sh" , "-c" , "echo 111 > 3.txt" }; process = Runtime.getRuntime().exec(cmd); BufferedReader br = new BufferedReader (new InputStreamReader (process.getInputStream(), Charset.forName("gbk" ))); String line = null ; while ((line = br.readLine()) != null ) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); } } }