在一些项目中可能会遇到使用java来调用操作系统命令完成一些操作,比如调用达梦的逻辑导出工具dexp来导出一些表,如果密码中涉及到特殊字符则会出现令人头疼的转义问题,现举例如下:
先需要在linux系统下导出TEST用户下的TEST表,TEST用户密码为TEST#
首先我们来分析这个需求:
我们知道正常的导出命令为
./dexp 用户名/密码@ip:端口 tables=test
如果我们直接照搬写成如下形式肯定是不正确的:
./dexp TEST/TEST#@127.0.0.1:5236 tables=test
因为密码中的井号#属于特殊字符,而dexp要求对于含有特殊字符的密码字符串用双引号引起来,而双引号在linux系统中又需要转义一下,则还需要在每个双引号前加一个转义符反斜杠\,于是命令就变成了:
./dexp TEST/\"TEST#\"@127.0.0.1:5236 tables=test
这个命令我们就可以直接拿到linux系统下进行数据导出了,这已经是一个实实在在可以执行的命令了,那如何将它放到java中进行调用呢?我们知道在java中可以使用Runtime.getRuntime().exec()方法来调用操作系统命令,而它提供了多种重载方法,其中我们比较常用的两种是:
1.public Process exec(String command)
2.public Process exec(String [] cmdArray)
其中第一种用起来最方便,可以直接将操作系统命令以String类型传入即可,对于我们这个例子来说则是:
String cmd = "/opt/dmhs/db/bin/dexp TEST/\"TEST#\"@192.168.239.128:5236 tables=test file=/opt/test.dmp";
Process p = Runtime.getRuntime().exec(cmd);
第二种则是以字符串数组的方式来传参,例如:
String [] cmd={"/bin/sh","-c","/opt/dmhs/db/bin/dexp TEST/\\\"TEST#\\\"@192.168.239.128:5236 tables=test file=/opt/test.dmp"};
Process p = Runtime.getRuntime().exec(cmd);
这种方式我们可以看出与上一种略有不同,首先第一个参数表示我们的命令使用/bin/sh来解释执行,第二个参数表示第三个参数包含一条命令,第三个参数就是我们要是用的命令,但是这个命令是由java传给操作系统,而java中对于特殊字符也需要转义,即命令中的反斜杠和双引号,其中\\”转义成\”交给操作系统。
上述两种方式都能达到相同的预期效果。对于密码中包含特殊字符的情况还有一种处理方式,如果密码中没有出现单引号,则可以将密码”TEST#”用单引号引起来去除双引号的特殊含义(无需使用反斜杠来进行转义),即改写成如下形式也可以正常执行:
./dexp TEST/'"TEST#"'@127.0.0.1:5236 tables=test
文章
阅读量
获赞