浅析Java执行外部命令的几个要点(4)——支持shell的"|","`","*","?"等特殊符号

本文探讨了在Java中如何执行包含特殊字符如'|','`','*','?'的外部命令。通过示例展示了如何使用CommandExec执行带有管道、通配符的shell命令,并提供了对shell字符串进行转义的方法,确保命令正确执行。最后,还展示了如何将命令的输出重定向到/dev/null。" 103862817,7468742,理解tf.nn.depth_to_space操作,"['深度学习', '张量操作', 'TensorFlow', '神经网络']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转贴请注明出处:http://blog.csdn.com/froole

在上一章已经验证了CommandExec可以很好的支持超时功能,通过它可以更方便的执行外部命令。
但是,这里还有一点需要注意——那就是shell(DOS)中的特殊符号。
因为用Java作为后台程序的系统,多运行于Unix/Linux,以下的介绍将基于如何shell来展开讨论。

假设,系统需要通过提取某个命令的标准输出,来进行某项处理。例如,搜索/路径下的xml文件并对结果处理,如下:
find / -name "*.xml" -type f | xargs java 相应程序
如果按照常规的方式,将以上的几个字串直接传递给Runtime.exec的参数,通过CommandExec的实现方法如下:
  1. CommandExec exec = new CommandExec();
  2. Process process = exec.exec(new String(){"find""/""-name""/"*.xml/"""-type""f""|""xargs""java""相应程序"});

但是,实际结果将事与愿违,因为,在解析"|"的时候是以特殊符号来解析,而JVM将把"|"作为普通的字符串来处理。
在通常的处理中,这种功能可以屏蔽命令溢出的漏洞,但是在特殊需求的时候,就不方便了。
当然,在特殊需求下也有解决方法,可以如下执行以下命令:
  1. CommandExec exec = new CommandExec();
  2. Process process = exec.exec(new String(){"shell""-c""/"find / -name '*.xml' -type f | xargs java 相应程序/""});

也就是把要执行的命令作为shell的一个参数让Runtime.exec执行,为shell命令加上-c参数就可以正常执行目标命令了。

细心的读者已经看出,用上面的方法,有一个缺点就是,如果动态生成命令,很容易发生命令溢出的漏洞。
这里有一个解决方法,就是设定一个前提,被执行命令,文字串都必须以单引号包含,那样就比较容易escape了。
escape的方法可以如下定义,并添加到CommandExec当中。
  1.     /**
  2.      *
  3.      * 对shell字串进行escape
  4.      *
  5.      * @param s 对象字串
  6.      * @return 返回escape之后的shell字串
  7.      */
  8.     public static String escapeShellSpecialCharacters(String s) {
  9.         StringBuilder sb = new StringBuilder(s.length() + 128);
  10.         sb.append('/'');
  11.         for (int i = 0; s != null && i < s.length(); i++) {
  12.             char c = s.charAt(i);
  13.             if (c == '/'') {
  14.                 sb.append('//');
  15.             }
  16.             sb.append(c);
  17.         }
  18.         sb.append('/'');
  19.         return sb.toString();
  20.     }
JVM执行外部命令功能的漏洞
到此为止,在Java中执行外部命令的方法以及注意点基本叙述完毕。但是,最后还有一点必须注意的就是JVM本身存在的一个漏洞。

这个漏洞的现象是,当被执行的外部命令,标准输出的量比较大的时候,程序会无故锁死。
特别是在JDK1.3版本尤为明显,在新版本中仍旧存在此漏洞。
不过,通过外部命令的执行方式,可以避免此漏洞的出现——通过重定向避免标准输出。
CommandExec的执行方法如下:
  1. CommandExec exec = new CommandExec();
  2. Process process = exec.exec(new String(){"shell""-c""/"find / -name '*.xml' -type f | xargs java 相应程序 > /dev/null/""});

到此结束,欢迎拍砖!

相关:
- 浅析Java执行外部命令的几个要点(1)
- 浅析Java执行外部命令的几个要点(2)
- 浅析Java执行外部命令的几个要点(3)
- 浅析Java执行外部命令的几个要点(4)

<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
转贴请注明出处: http://blog.youkuaiyun.com/froole
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值