常用的命令执行函数
java.lang.Runtime
java.lang.ProcessBuilder
java.lang.ProcessImpl
调用链:java.lang.Runtime
—>java.lang.ProcessBuilder
—>java.lang.processImpl
—>java.lang.UNIXProcess
在java1.9中UNIXProcess
被合并到了ProcessImpl
Java.lang.Runtime
该方法的参数有两种形式,一种是字符串类型,另一种则是数组类型
字符串类型的参数:
String cmd ="ipconfig /all";
Process exec = Runtime.getRuntime().exec(cmd);
数组型参数
String [] cmds={"ipconfig","/all"};
Process exec = Runtime.getRuntime().exec(cmds);
示例
@Test
public void Test1() throws IOException {
String cmd ="ipconfig /all";
Process exec = Runtime.getRuntime().exec(cmd);
// 读取命令执行的结果并打印输出
BufferedReader reader = new BufferedReader(new InputStreamReader(exec.getInputStream(), Charset.forName("GBK")));
String line;
System.out.println("命令执行结果:");
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
// 关闭输入流
reader.close();
}
通过反射调用
@Test
public void Test6() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
Class<?> aClass = Class.forName("java.lang.Runtime");
Method exec = aClass.getDeclaredMethod("exec", String.class);
Object getRuntime = aClass.getDeclaredMethod("getRuntime").invoke(aClass);
Object invoke = exec.invoke(getRuntime,"calc");
}
隐藏关键字形式
//隐藏Runtime关键字
@Test
public void Test7() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
String str="calc";
// 定义"java.lang.Runtime"字符串变量
String rt = new String(new byte[]{106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 82, 117, 110, 116, 105, 109, 101});
// 反射java.lang.Runtime类获取Class对象
Class<?> c = Class.forName(rt);
// 反射获取Runtime类的getRuntime方法
Method m1 = c.getMethod(new String(new byte[]{103, 101, 116, 82, 117, 110, 116, 105, 109, 101}));
// 反射获取Runtime类的exec方法
Method m2 = c.getMethod(new String(new byte[]{101, 120, 101, 99}), String.class);
// 反射调用Runtime.getRuntime().exec(calc)方法
Object obj2 = m2.invoke(m1.invoke(null, new Object[]{}), new Object[]{str});
}
Java.lang.ProcessBuilder
该方法执行系统命令的方式也是有两种,分别是:
ProcessBuilder(List<String> command)
ProcessBuilder(String... command)
一种是字符串列表形式,另外一种是字符串数组形式,其实看起来都是差不多的
import java.io.IOException;
import java.util.Arrays;
public class ProcessBuilderExample {
public static void main(String[] args) {
try {
// 使用 List<String> 形式的命令参数
List<String> commandList = Arrays.asList("ls", "-l", "/tmp");
ProcessBuilder processBuilder1 = new ProcessBuilder(commandList);
// 使用 String... 形式的命令参数
ProcessBuilder processBuilder2 = new ProcessBuilder("ls", "-l", "/tmp");
// 启动进程
Process process1 = processBuilder1.start();
Process process2 = processBuilder2.start();
// 等待进程执行完毕
int exitCode1 = process1.waitFor();
int exitCode2 = process2.waitFor();
System.out.println("Command executed with exit code (List<String>): " + exitCode1);
System.out.println("Command executed with exit code (String...): " + exitCode2);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
使用示例二
@Test
public void Test3() throws IOException {
ProcessBuilder processBuilder = new ProcessBuilder("ipconfig","/all");
Process start = processBuilder.start();
InputStream inputStream = start.getInputStream();
BufferedReader gbk = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("GBK")));
String res;
while ((res = gbk.readLine())!=null){
System.out.println(res);
}
}
Java.lang.ProcessImpl
该类并不是一个public
类,并不能直接调用,但是可以通过反射的形式进行调用,下面是两个示例
示例一
@Test
public void Test4() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, IOException {
Class<?> aClass = Class.forName("java.lang.ProcessImpl");
Method start = aClass.getDeclaredMethod("start", String[].class, Map.class, String.class, ProcessBuilder.Redirect[].class, boolean.class);
start.setAccessible(true);
InputStream invoke = (InputStream) start.invoke(null, new String[]{"calc"}, null, null, null, false);
}
示例二
@Test
public void Test5() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, IOException {
Class<?> aClass = Class.forName("java.lang.ProcessImpl");
Method start = aClass.getDeclaredMethod("start", String[].class, Map.class, String.class, ProcessBuilder.Redirect[].class, boolean.class);
start.setAccessible(true);
Process process = (Process) start.invoke(null, new String[]{"ipconfig", "/all"}, null, null, null, false);
// 获取进程的输入流
InputStream inputStream = process.getInputStream();
// 读取输入流中的内容
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream,Charset.forName("GBK")));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
// 关闭输入流
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
// 等待进程执行完毕
try {
int exitCode = process.waitFor();
System.out.println("Command executed with exit code: " + exitCode);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
相关笔记代码已上传至Git仓库JavaCodeAudit