后续业务可能需要在程序中运行指令, 所以这里简单探究了一下, 分别从win和linux两个平台进行研究, 又以为java是跨平台语言, 可能二者之间的区别应该只是返回内容与输入指令的不同. (还不是在win上开发)

1. 如何使用

  • Runtime.getRuntime().exec("notepad");

  • RuntimeUtil.exec("notepad"); // hutool

    了解了使用方法, 接下来探究几个问题.

2. 如何获取返回值

  • 参考: java执行cmd命令并获取返回结果字符串

    public static String execCMD(String command) {
    StringBuilder sb = new StringBuilder();
    try {
    Process process = Runtime.getRuntime().exec(command);
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
    String line;
    while ((line = bufferedReader.readLine()) != null) {
    sb.append(line).append("\n");
    }
    } catch (Exception e) {
    return e.toString();
    }
    return sb.toString();
    }
  • hutool中用法1: String str = RuntimeUtil.execForStr("ipconfig");

  • hutool中用法2: List<String> ss = RuntimeUtil.execForLines("ipconfig");

    需要注意一点:

    参数command: a string array containing the program and its arguments.

    以上所有的command 并不是cmd命令行中的命令, 而是在运行窗口(win+r)可以运行的, 比如dir这个典型的cmd命令, 在win+r的运行窗口就不能运行. 可以使用cmd /c dir 来运行.

    /c 是运行完不显示窗口, /k是运行完显示, 其他参数可在cmd指令中打出 cmd /? 查看

3. 模拟在取结果时候堵塞进程

  • 代码

    System.err.println(DateUtil.format(new Date(), DatePattern.NORM_DATETIME_MS_PATTERN));
    System.err.println(RuntimeUtil.execForStr("ping 192.168.0.222 /n 2"));
    System.err.println(DateUtil.format(new Date(), DatePattern.NORM_DATETIME_MS_PATTERN));
  • 输出:

    2022-07-15 16:34:50.523
    
    正在 Ping 192.168.0.222 具有 32 字节的数据:
    来自 192.168.0.222 的回复: 字节=32 时间=49ms TTL=128
    来自 192.168.0.222 的回复: 字节=32 时间=16ms TTL=128 192.168.0.222 的 Ping 统计信息:
    数据包: 已发送 = 2,已接收 = 2,丢失 = 0 (0% 丢失),
    往返行程的估计时间(以毫秒为单位):
    最短 = 16ms,最长 = 49ms,平均 = 32ms 2022-07-15 16:34:51.575
  • 结论

    确实可以看到两个时间相差1s左右. 可以将 ping ** /n 2中的2调大一些查看区别.

    接下来我们把ping命令换成notepadcmd /c notepad, 可以看到直接堵死了.

    在linux系统的终端运行firefox, 在终端会显示对应日志.

    对应到我们例子中, 执行exec方法时候会有返回一个进程p,

    我们就是从进程p的输入流中拿到的程序/指令返回的内容(写在命令行中的内容)

    正常情况下程序执行完就自动结束了, 但是记事本/firefox不会自动停止,

    所以线程会一直占用着, 与是否写日志无关.

    如果这种情况下获取返回内容, 可以将返回内容写入全局数组

    另外使用线程异步进行读取.

4. 刨析进程的从属关系

  • 代码(放在接口中测试)

    ThreadUtil.execAsync(() ->
    RuntimeUtil.execForStr("notepad"));
    ThreadUtil.execAsync(() ->
    RuntimeUtil.execForStr("ping 192.168.0.222 /t"));
    ThreadUtil.execAsync(() ->
    RuntimeUtil.execForStr("notepad"));
  • 运行, 使用Process Explorer软件查看

    运行一次.

    运行3次.

    可以看到执行的这些都是java.exe的子线程, 那么当我们停止java.exe程序时候, 其下的子程序也会一起被杀掉吗?

    其实不会, 这些线程会被移动到根目录下

    这很疑惑, 接下来来一个对比类型, 打开命令行输入`ping localhost \t, 查看进程

    可以看到cmd是在explorer.exe下的进程, 就是我们的资源管理器(包括桌面这些, 并不只是我的电脑),

    而且不同之处是ping.exe, 代码生成的会自带一个conhost, 手动执行的则平级生成的.

    然后又测试了使用Runtime.getRuntime().exec("ping 192.168.0.111 /t");生成, 发现当关闭java.exe时还是会移动到最后.

    手动杀掉java也不会影响(树影响), 但是手动命令行中启动的ping在只杀掉命令行时候会一同将子目录杀掉


    尚未在实际中应用, 暂时到此为止.

java中运行指令浅析的更多相关文章

  1. 怎样在Java中运行Hive命令或HiveQL

    这里所说的在Java中运行Hive命令或HiveQL并非指Hive Client通过JDBC的方式连接HiveServer(or HiveServer2)运行查询,而是简单的在部署了HiveServe ...

  2. Java中运行javascript代码

    Java中运行javascript代码 1.Java 代码 2.JS代码 2.1demoWithParams.js 2.2demoWithListParams.js 原文作者:russle 原文地址: ...

  3. Java中运行时异常和非运行时异常什么鬼?

    Java中的异常分类 RuntimeException(也称unchecked exceptions,运行时异常) 就是我们在开发中测试功能时程序终止,控制台出现的异常.(一般来说,出现运行时异常基本 ...

  4. Java中运行动态脚本

    这里主要总结Java中集成Groovy的应用. Groovy可以与Java完美集成来扩展我们的应用,比如替代Java+jexl实现算式表达式计算或其它功能.在Ofbiz中也集成了Groovy来执行一些 ...

  5. IDEA清空控制台以及Java中运行cmd命令实现清屏操作

    IDEA中清空控制台方法 在网上有看到各种的实现方法,比如: Runtime.getRuntime().exec("cls"); 或者: public static void cl ...

  6. Java中的HashMap 浅析

    在Java的集合框架中,HashSet,HashMap是用的比较多的一种,顺序结构的ArrayList.LinkedList这种也比较多,而像那几个线程同步的容器就用的比较少,像Vector和Hash ...

  7. java中io流浅析

    1.java.io包下File类:java程序中的此类的一个对象,就对应着硬盘中的一个文件或网络中的一个资源.File file1 = new File("d:\\io\\helloworl ...

  8. Java中的字符串常量池和JVM运行时数据区的相关概念

    什么是字符串常量池 JVM为了减少字符串对象的重复创建,其维护了一个特殊的内存,这段内存被成为字符串常量池或者字符串字面量池 工作原理 当代码中出现字面量形式创建字符串对象时,JVM首先会对这个字面量 ...

  9. java中堆栈(stack)和堆(heap)(还在问静态变量放哪里,局部变量放哪里,静态区在哪里.....进来)

    (1)内存分配的策略 按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的. 静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编 译时就可以给 ...

  10. 3.2 java中堆栈(stack)和堆(heap)(还在问静态变量放哪里,局部变量放哪里,静态区在哪里.....进来)

    (1)内存分配的策略 按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的. 静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编 译时就可以给 ...

随机推荐

  1. biancheng-Spring MVC-HandlerAdapter

    二.HandlerAdapter 根据 Handler 来找到支持它的 HandlerAdapter,通过 HandlerAdapter 执行这个 Handler 得到 ModelAndView 对象 ...

  2. RocketMQ实战—6.生产优化及运维方案

    大纲 1.RocketMQ集群如何进行权限机制的控制 2.如何对RocketMQ集群进行消息堆积的追踪 3.如何处理RocketMQ的百万消息积压问题 4.针对RocketMQ集群崩溃的金融级高可用方 ...

  3. 1.6~THUWC 的总结

    THUWC 虽然拿到了一等奖,但是其实不如预期的发挥. Day1 获得 260~300 分.快速地想出了 T1T2 然后在调试上花费了很多的时间,T3 没有想出来,T4 想出了 \(O(n\log^3 ...

  4. Nityacke's 分块(未补全)

    P2801 教主的魔法 区间加区间查询一个数排名. 对于每个块,维护其有序序列.修改时散块暴力重构,整块打tag. 查询是简单的.时间复杂度 \(O(n\log B+\dfrac{qn}{B}\log ...

  5. Luogu P11363 NOIP2024 树的遍历 题解 [ 紫 ] [ 树形 dp ] [ 组合计数 ] [ adhoc ]

    树上遍历:CCF 难得一遇的好题! 参考了洛谷的第一篇题解,所以思路会有点相似. 部分分 当 \(k=1\) 时,显然方案总数为 \(\prod_{i=1}^{n}(d_i-1)!\),因为进入一个子 ...

  6. FreeSql学习笔记——6.修改

    前言   FreeSql 提供丰富的数据库更新功能,支持单条或批量更新,支持更新指定的字段,在特定的数据库执行还可以返回更新后的记录.与删除一样,没有条件的话不会执行,避免全表修改到全表:     指 ...

  7. NFS服务器离线问题解决

    NFS服务器离线问题解决 NFS服务器挂了会导致挂载的NFS客户端主机卡顿延迟,或者提示找不到文件 因为在执行一些命令的时候会自动去同步,用作同步的NFS服务端挂了,命令执行就会卡住 不过听说NFS还 ...

  8. Windows下快捷方式 (*.lnk) 的使用技巧整理

    日常应用中,许多软件都会在安装过程最后一步添加多个命令,针对其应用创建快捷方式发送到桌面以及快速启动栏和开始菜单,供人们快速找到并打开.在我的使用习惯中也会将诸多常用的应用右键-发送到-桌面快捷方式来 ...

  9. [SWPUCTF 2021 新生赛]ez_unserialize

    概括 这是一道PHP反序列化的CTF赛题,本意是想用这道题对PHP反序列化进行一定的学习. 过程 我们打开赛题,看看内容 没有发现什么东西,看看他的页面代码 根据他的提示,感觉是存在一个robots. ...

  10. 关于我第二周学习kotlin这门语言

    有关kotlin的知识点: 在学习lambda之前,我们先了解一下什么是lambda,简答来说就是一小段代码块,并且我们可以将这个代码块在函数之间传递,这是函数式编程的一个重要特性. 通常我们会需要一 ...