当前位置:   article > 正文

Java-执行系统命令&进程-进阶篇

Java-执行系统命令&进程-进阶篇

结论

结论1:Runtime.getRuntime().exec(CMD)中执行命令,等同于Win+R调起"运行"执行CMD。

结论2:不管按多少次Win+R,都只能调起一个运行

结论3:Java通过Runtime.getRuntime().exec()创建子进程是入参字符串中首个程序,比如:cmd /c dir,cmd.exe是Runtime.getRuntime().exec()创建的子进程,Process类的waitFor、isAlive、exitValue都是根据cmd.exe执行情况判断的,而不是dir。

结论4:cmd /c如果想测试wairFor是否生效,不可以使用timeout命令,可以通过ping www.baidu.com -n 10来验证。


问题X:Windows下Runtime.getRuntime().exec()具体是指什么?


 问题X:Win+R调起“运行”对应哪个可执行文件?

explorer.exe Shell:::{2559a1f3-21d7-11d4-bdaf-00c04f60b9f0}

参考资料:

8 ways to open the Run command window in Windows - Digital Citizen


问题X:Win+R调起“运行”,哪些程序可以执行?哪些程序不可以执行?

  • 可以执行
    • notepad、mspaint、calc、ping等
    • cmd /c、cmd /k、cmd /c start、cmd /k start
  • 不可以执行
    • dir


问题X:

  • idea64.exe、java.exe、cmd.exe、PING.EXE关系?
  • isAlive、waitFor、exitValue依据哪个进程执行情况?
  • isAlive、waitFor、exitValue哪个会阻塞主进程?

idea64.exe

        java.exe:主进程

                cmd.exe:Runtime.getRuntime().exec()创建的子进程

                        PING.EXE

  1. import java.io.BufferedReader;
  2. import java.io.IOException;
  3. import java.io.InputStreamReader;
  4. import java.lang.management.ManagementFactory;
  5. /**
  6. * 主进程:java.exe
  7. * 子进程:cmd.exe
  8. * 子进程又调用了PING.EXE
  9. * Process类的isAlive、waitFor、exitValue依据子进程cmd.exe的运行情况,而不是PING.EXE
  10. * waitFor会阻塞主进程,exitValue不会阻塞主进程,如果子进程未结束调用exitValue,程序会报错
  11. */
  12. public class Test {
  13. public static void main(String[] args) throws IOException, InterruptedException {
  14. Process process = null;
  15. InputStreamReader reader = null;
  16. BufferedReader br = null;
  17. String line = null;
  18. String mainProcess = ManagementFactory.getRuntimeMXBean().getName();
  19. System.out.println(mainProcess);
  20. System.out.println(mainProcess.split("@")[0]);
  21. process = Runtime.getRuntime().exec("cmd /c tasklist | findstr " + mainProcess.split("@")[0]);
  22. reader = new InputStreamReader(process.getInputStream(), "GBK");
  23. br = new BufferedReader(reader);
  24. line = null;
  25. while ((line = br.readLine()) != null) {
  26. System.out.println(line);
  27. }
  28. reader.close();
  29. br.close();
  30. /**
  31. * Runtime.getRuntime().exec()子进程是cmd.exe,不是PING.EXE
  32. * Process类的isAlive、waitFor、exitValue依据子进程cmd.exe的运行情况,而不是PING.EXE
  33. *
  34. * waitFor会阻塞主进程,exitValue不会阻塞主进程,如果子进程未结束调用exitValue,程序会报错
  35. *
  36. * cmd /c ping www.baidu.com -n 5:waitFor有效,因为ping结束后cmd.exe才结束
  37. * cmd /c start ping www.baidu.com -n 5:waitFor其实也有效,但是给人感觉无效,主要是因为cmd.exe刚调起就结束了。
  38. * 这个例子充分说明,Process类的waitFor方法主要看子进程cmd.exe是否执行完毕,跟PING.EXE是否执行完毕无关
  39. */
  40. for (int i = 0; i < 3; i++) {
  41. process = Runtime.getRuntime().exec("cmd /c ping www.baidu.com -n 5");
  42. // 如果exitValue非0,需要打印error信息
  43. // reader = new InputStreamReader(process.getInputStream(), "GBK");
  44. // br = new BufferedReader(reader);
  45. // line = null;
  46. // while ((line = br.readLine()) != null) {
  47. // System.out.println(line);
  48. // }
  49. // 判断子进程cmd.exe是否结束
  50. System.out.println("isAlive: " + process.isAlive());
  51. // 等待子进程cmd.exe结束,同时会阻塞主进程java.exe
  52. process.waitFor();
  53. // 获取子进程cmd.exe的运行结果,不会阻塞主进程java.exe。
  54. // 如果命令没有执行完毕,调用此接口会报错
  55. System.out.println("exitValue " + process.exitValue());
  56. }
  57. }
  58. }

"C:\Program Files\Java\jdk-17.0.1\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2021.3.2\lib\idea_rt.jar=52415:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2021.3.2\bin" -Dfile.encoding=UTF-8 -classpath C:\Users\IdeaProjects\test\out\production\test Test
1652@DESKTOP-OLO3A1L
1652
java.exe                      1652 Console                    1     43,092 K
isAlive: true
exitValue 1
isAlive: true
exitValue 1
isAlive: true
exitValue 1

Process finished with exit code 0


问题X: exec()方法参数 与 START命令参数 对比

  • Runtime.getRuntime().exec(String command, String[] envp, File dir)
    • String command
    • String[] envp
    • File dir
  • Runtime.getRuntime().exec(String[] cmdarray, String[] envp, File dir)
    • String[] cmdarray
    • String[] envp
    • File dir
  • START命令
    • [<command> [<parameter>... ] | <program> [<parameter>... ]]    指定要启动的命令或程序。
    • /i    将Cmd.exe环境传递给新的命令 提示符 窗口。 如果 未指定 /i ,则使用当前环境。
    • /d <path>    指定启动目录。

问题X:

  • cmd /ccmd /kcmd /c startcmd /k start 命令区别

场景1:cmd /c ping www.baidu.com -n 10

  • 创建几个cmd.exe:1个
  • 执行结束后cmd窗口是否关闭:自动关闭
  • Java是否可以获取命令执行结果:可以获取

  1. import java.io.BufferedReader;
  2. import java.io.IOException;
  3. import java.io.InputStreamReader;
  4. public class Test {
  5. public static void main(String[] args) throws IOException, InterruptedException {
  6. for (int i = 0; i < 3; i++) {
  7. Process process = Runtime.getRuntime().exec("cmd /c ping www.baidu.com -n 5");
  8. BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
  9. String line = null;
  10. while ((line = br.readLine()) != null) {
  11. System.out.println(line);
  12. }
  13. process.waitFor();
  14. System.out.println("isAlive: " + process.isAlive());
  15. System.out.println("exitValue: " + process.exitValue());
  16. System.out.println("该打印主要用于判断waitFor是否生效?");
  17. }
  18. }
  19. }


场景2:cmd /k ping www.baidu.com -n 10

  • 创建几个cmd.exe:1个
  • 执行结束后cmd窗口是否关闭:不会关闭
  • Java是否可以获取命令执行结果:可以获取

  1. import java.io.BufferedReader;
  2. import java.io.IOException;
  3. import java.io.InputStreamReader;
  4. public class Test {
  5. public static void main(String[] args) throws IOException, InterruptedException {
  6. for (int i = 0; i < 3; i++) {
  7. Process process = Runtime.getRuntime().exec("cmd /k ping www.baidu.com -n 5");
  8. BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
  9. String line = null;
  10. while ((line = br.readLine()) != null) {
  11. System.out.println(line);
  12. }
  13. process.waitFor();
  14. System.out.println("isAlive: " + process.isAlive());
  15. System.out.println("exitValue: " + process.exitValue());
  16. System.out.println("该打印主要用于判断waitFor是否生效?");
  17. }
  18. }
  19. }

 


场景3:cmd /c start ping www.baidu.com -n 100

  • 创建几个cmd.exe:1个。要特别注意,因为cmd.exe不会执行任何操作,所以,打开一下就迅速关闭了,所以,tasklist没有检测到创建的cmd.exe
  • 执行结束后cmd窗口是否关闭:自动关闭
  • Java是否可以获取命令执行结果:无法获取

  1. import java.io.BufferedReader;
  2. import java.io.IOException;
  3. import java.io.InputStreamReader;
  4. public class Test {
  5. public static void main(String[] args) throws IOException, InterruptedException {
  6. for (int i = 0; i < 10; i++) {
  7. Process process = Runtime.getRuntime().exec("cmd /c start ping www.baidu.com -n 10");
  8. BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
  9. String line = null;
  10. while ((line = br.readLine()) != null) {
  11. System.out.println(line);
  12. }
  13. process.waitFor();
  14. System.out.println("isAlive: " + process.isAlive());
  15. System.out.println("exitValue: " + process.exitValue());
  16. System.out.println("该打印主要用于判断waitFor是否生效?");
  17. }
  18. }
  19. }


场景4:cmd /k start "ping windows" ping www.baidu.com -n 100

  • 创建几个cmd.exe:1个
  • 执行结束后cmd窗口是否关闭:不会关闭
  • Java是否可以获取命令执行结果:无法获取

  1. import java.io.BufferedReader;
  2. import java.io.IOException;
  3. import java.io.InputStreamReader;
  4. public class Test {
  5. public static void main(String[] args) throws IOException, InterruptedException {
  6. for (int i = 0; i < 3; i++) {
  7. Process process = Runtime.getRuntime().exec("cmd /k start ping www.baidu.com -n 5");
  8. BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
  9. String line = null;
  10. while ((line = br.readLine()) != null) {
  11. System.out.println(line);
  12. }
  13. process.waitFor();
  14. System.out.println("isAlive: " + process.isAlive());
  15. System.out.println("exitValue: " + process.exitValue());
  16. System.out.println("该打印主要用于判断waitFor是否生效?");
  17. }
  18. }
  19. }


问题X:ping www.baidu.com -n 5 和 cmd /c ping www.baidu.com -n 5 区别 

  • 创建几个cmd.exe:均1个
  • 执行结束后cmd窗口是否关闭:均自动关闭
  • Java是否可以获取命令执行结果:均可以获取

用途(被动式扫描系统):

方案一:cmd.exe是子进程

python.exe:主进程

        cmd.exe:子进程

                wvs_console.exe:由子进程创建的,进程状态和运行结果不可控

                        sqlmapapi.py

方案二:wvs_console.exe是子进程

python.exe:主进程

        wvs_console.exe:子进程

                sqlmapapi.py


参考资料:

java runtime exec 输出_[转]Java中Runtime.exec的一些事_Elendil Zheng的博客-CSDN博客

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/290655
推荐阅读
相关标签
  

闽ICP备14008679号