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

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.management.ManagementFactory;

/**
 * 主进程:java.exe
 * 子进程:cmd.exe
 * 子进程又调用了PING.EXE
 * Process类的isAlive、waitFor、exitValue依据子进程cmd.exe的运行情况,而不是PING.EXE
 * waitFor会阻塞主进程,exitValue不会阻塞主进程,如果子进程未结束调用exitValue,程序会报错
 */
public class Test {
    public static void main(String[] args) throws IOException, InterruptedException {
        Process process = null;
        InputStreamReader reader = null;
        BufferedReader br = null;
        String line = null;

        String mainProcess = ManagementFactory.getRuntimeMXBean().getName();
        System.out.println(mainProcess);
        System.out.println(mainProcess.split("@")[0]);

        process = Runtime.getRuntime().exec("cmd /c tasklist | findstr " + mainProcess.split("@")[0]);
        reader = new InputStreamReader(process.getInputStream(), "GBK");
        br = new BufferedReader(reader);
        line = null;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }
        reader.close();
        br.close();

        /**
         * Runtime.getRuntime().exec()子进程是cmd.exe,不是PING.EXE
         * Process类的isAlive、waitFor、exitValue依据子进程cmd.exe的运行情况,而不是PING.EXE
         *
         * waitFor会阻塞主进程,exitValue不会阻塞主进程,如果子进程未结束调用exitValue,程序会报错
         *
         * cmd /c ping www.baidu.com -n 5:waitFor有效,因为ping结束后cmd.exe才结束
         * cmd /c start ping www.baidu.com -n 5:waitFor其实也有效,但是给人感觉无效,主要是因为cmd.exe刚调起就结束了。
         * 这个例子充分说明,Process类的waitFor方法主要看子进程cmd.exe是否执行完毕,跟PING.EXE是否执行完毕无关
         */
        for (int i = 0; i < 3; i++) {
            process = Runtime.getRuntime().exec("cmd /c ping www.baidu.com -n 5");
            // 如果exitValue非0,需要打印error信息
//            reader = new InputStreamReader(process.getInputStream(), "GBK");
//            br = new BufferedReader(reader);
//            line = null;
//            while ((line = br.readLine()) != null) {
//                System.out.println(line);
//            }

            // 判断子进程cmd.exe是否结束
            System.out.println("isAlive: " + process.isAlive());

            // 等待子进程cmd.exe结束,同时会阻塞主进程java.exe
            process.waitFor();

            // 获取子进程cmd.exe的运行结果,不会阻塞主进程java.exe。
            // 如果命令没有执行完毕,调用此接口会报错
            System.out.println("exitValue " + process.exitValue());
        }
    }
}

"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是否可以获取命令执行结果:可以获取

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Test {
    public static void main(String[] args) throws IOException, InterruptedException {
        for (int i = 0; i < 3; i++) {
            Process process = Runtime.getRuntime().exec("cmd /c ping www.baidu.com -n 5");
            BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line = null;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
            process.waitFor();
            System.out.println("isAlive: " + process.isAlive());
            System.out.println("exitValue: " + process.exitValue());
            System.out.println("该打印主要用于判断waitFor是否生效?");
        }
    }
}


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

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

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Test {
    public static void main(String[] args) throws IOException, InterruptedException {
        for (int i = 0; i < 3; i++) {
            Process process = Runtime.getRuntime().exec("cmd /k ping www.baidu.com -n 5");
            BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line = null;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
            process.waitFor();
            System.out.println("isAlive: " + process.isAlive());
            System.out.println("exitValue: " + process.exitValue());
            System.out.println("该打印主要用于判断waitFor是否生效?");
        }
    }
}

 


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

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

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Test {
    public static void main(String[] args) throws IOException, InterruptedException {
        for (int i = 0; i < 10; i++) {
            Process process = Runtime.getRuntime().exec("cmd /c start ping www.baidu.com -n 10");
            BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line = null;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
            process.waitFor();
            System.out.println("isAlive: " + process.isAlive());
            System.out.println("exitValue: " + process.exitValue());
            System.out.println("该打印主要用于判断waitFor是否生效?");
        }
    }
}


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

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

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Test {
    public static void main(String[] args) throws IOException, InterruptedException {
        for (int i = 0; i < 3; i++) {
            Process process = Runtime.getRuntime().exec("cmd /k start ping www.baidu.com -n 5");
            BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line = null;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
            process.waitFor();
            System.out.println("isAlive: " + process.isAlive());
            System.out.println("exitValue: " + process.exitValue());
            System.out.println("该打印主要用于判断waitFor是否生效?");
        }
    }
}


问题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博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值