java执行cmd命令是遇到一些特殊字符处理丢失

:当时要执行kettle命令的时候,遇到kettle的命令符号丢失,如果是linux环境,使用如下接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package com.pactera.common.util;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.cli.*;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.*;
import org.junit.Test;
import java.io.ByteArrayOutputStream;
import java.util.Collection;
/**
* @author song
* @date created in 2018-01-19 18:49
*/
public class ExecuteShell {
public static JSONObject callCMD(String shellInfo) {
System.out.println("Cmd接收到的命令---"+shellInfo);
JSONObject json = new JSONObject();
String error = "";
int execute = 1;
String out="";
try {
CommandLine commandline = CommandLine.parse(shellInfo);
DefaultExecutor exec = new DefaultExecutor();
exec.setExitValue(0);
ExecuteWatchdog watchdog = new ExecuteWatchdog(600 * 1000);
exec.setWatchdog(watchdog);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ByteArrayOutputStream errorStream = new ByteArrayOutputStream();
PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream, errorStream);
exec.setStreamHandler(streamHandler);
execute = exec.execute(commandline);
out = outputStream.toString("gbk");
error = errorStream.toString("gbk");
System.out.println(out);
System.out.println(error);
} catch (Exception e) {
json.put("statusCode", 1);
json.put("msg", "Failed to call shell's command and the return status's is:1 "+error );
}
json.put("statusCode" , execute);
json.put("msg" , out);
return json;
}
/**
* 创建commandline对象
*
* @param args
* @return
* @throws ParseException
*/
private static CommandLine getCommandLine(String args, Options mergeOptions) throws ParseException {
CommandLineParser parser = new DefaultParser();
HelpFormatter hf = new HelpFormatter();
hf.printHelp(args, "", mergeOptions, "");
// return parser.parse(mergeOptions, new String[]{args});
return null;
}
/**
* 合并options
*
* @param optionsArgs options项
* @return 合并后的options
*/
private static Options mergeOptions(Options... optionsArgs) {
Options allOptions = new Options(); // 合并所有options,如果不合并单独使用,会出现问题
for (Options options : optionsArgs) {
Collection<Option> options1 = options.getOptions();
for (Option option : options1) {
allOptions.addOption(option);
}
}
return allOptions;
}
@Test
public void test() throws ParseException {
// 模拟命令行参数
String args = "sdo";
}
/* public static void main(String[] args) throws ParseException {
String argss[]={"-t 1000"};
//定义
Options options = new Options();
options.addOption("ipconfig", false, "list help");//false代表不强制有
options.addOption("ipconfig", true, "set time on system");
//解析
//1.3.1中已经弃用针对不同格式入参对应的解析器
//CommandLineParser parser = new PosixParser();
CommandLineParser parser = new DefaultParser();
CommandLine cmd = parser.parse(options, args);
//查询交互
//你的程序应当写在这里,从这里启动
String formatstr = "ipconfig";
HelpFormatter hf = new HelpFormatter();
hf.printHelp(formatstr, "", options, "");
return;
}*/
public static void main(String[] args) {
try {
String command = " E:\\tool\\data-integration\\kitchen.bat /rep:kettle /dir:/ /user:admin /pass:admin /level:Basic /job:EDW_FENFA_JOB -param:\"DBTYPE=ORACLE\" -param:\"TABLE_NAME=omdata.S24_SEAT_HISTORY\" -param:\"EDW_TABLE_NAME=S24_SEAT_HISTORY\" -param:\"COLUMNS=T.ID,T.BUS_ID,T.LAST_REST,T.REST,T.LAST_UPDATETIME,T.UPDATE_TIME\" -param:\"USER_NAME=yyy\" -param:\"CONDITIONS=TO_DATE('20160310','YYYYMMDD')=T.ETL_DT\" -param:\"DATA_DT=20160310\"";
CommandLine commandline = CommandLine.parse(command);
DefaultExecutor exec = new DefaultExecutor();
exec.setExitValue(0);
ExecuteWatchdog watchdog = new ExecuteWatchdog(60*1000);
exec.setWatchdog(watchdog);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ByteArrayOutputStream errorStream = new ByteArrayOutputStream();
PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream,errorStream);
exec.setStreamHandler(streamHandler);
int execute = exec.execute(commandline);
String out = outputStream.toString("gbk");
String error = errorStream.toString("gbk");
System.out.println("out"+out);
System.out.println("error"+error);
System.out.println("exit: " + execute);
} catch (Exception e) {
return;
}
}
}
1. 我当时的测试环境是Windows,使用了上面的接口处理kettle命令,这个 CommandLine commandline = CommandLine.parse(shellInfo);的时候,命令还是正常的,到了处理的时候execute = exec.execute(commandline);就导致了命令符号的一些丢失,比如;=
2. 后来想了很久,查找很多资料换了一种方式处理,不能通过转义字符来处理,为什么不换一种处理cmd命令的方式了,后来换了如下方式在windoes就可以了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package com.pactera.common.util;
/**
* @author song
* @date created in 2018-02-01 15:36
*/
import com.alibaba.fastjson.JSONObject;
import com.pactera.common.model.ResultModel;
import org.apache.log4j.Logger;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class CallCmdUtils {
private static Logger logger = Logger.getLogger(CallCmdUtils.class);
public static void executeCmd(String cmd){
if(cmd == null || cmd.equals("")){
return;
}
logger.info("执行命令:"+cmd);
String[] cmds = new String[]{"/bin/sh","-c",cmd};
try {
Runtime.getRuntime().exec(cmds);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 执行本地命令 cmd格式 windows 环境下查询360运行exe程序: cmd /c tasklist | findstr
* "360.*[.exe]"
*
* @param cmd
* @return
*/
public static ResultModel executeLocalCmd(String cmd) {
ResultModel model = null;
if(cmd == null || cmd.equals("")){
model.setStatusCode("1");
return model;
}
logger.info("执行命令:"+cmd);
String[] cmds = new String[]{cmd};
StringBuffer sb = new StringBuffer(255);
try {
Process process = Runtime.getRuntime().exec(cmds);
process.waitFor();
int result = process.exitValue();
if(result == 0){
/* model.setStatusCode("0");*/
InputStream in = process.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String dataline = null;
while ((dataline = br.readLine()) != null) {
sb.append(dataline).append("\n");
}
br.close();
in.close();
/*model.setMessage(sb.toString().trim());*/
}else{
InputStream in = process.getErrorStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String dataline = null;
while ((dataline = br.readLine()) != null) {
sb.append(dataline).append("\n");
}
br.close();
in.close();
/* model.setStatusCode("1");
model.setMessage(sb.toString().trim());*/
}
} catch (Exception e) {
e.printStackTrace();
}
return model;
}
public static JSONObject execCommand(String command){
JSONObject json = new JSONObject();
int execute = 0;
try {
Process proc = Runtime.getRuntime().exec(command);
//为了防止命令进程阻塞,添加两线程处理输出信息
new StreamGobbler(proc.getErrorStream(),"["+command+"]ERROR").start();
new StreamGobbler(proc.getInputStream(),"["+command+"]STDOUT").start();
if(proc.waitFor()==0){
logger.error("执行["+command+"]命令成功");
json.put("statusCode", 0);
json.put("msg" , "执行["+command+"]命令成功");
}else{
logger.error("执行["+command+"]命令出错");
json.put("statusCode", 1);
json.put("msg" , "执行["+command+"]命令出错");
}
} catch (IOException ex) {
logger.error("执行["+command+"]命令IO异常",ex);
json.put("msg" , "执行["+command+"]命令IO异常"+ex);
json.put("statusCode", 1);
} catch (InterruptedException ex) {
logger.error("执行["+command+"]命令被中断",ex);
json.put("msg" , "执行["+command+"]命令被中断"+ex);
json.put("statusCode", 1);
}
return json;
}
}
我试了几个方法,后来用了最后一个:execCommand(String command)这个方法就可以了。在附上一个帮助StreamGobbler.java 如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package com.pactera.common.util;
/**
* @author song
* @date created in 2018-02-01 15:37
*/
import org.apache.log4j.Logger;
import java.io.*;
/**
* 用于处理Runtime.getRuntime().exec产生的错误流及输出流
* @author shaojing
*
*/
public class StreamGobbler extends Thread {
static Logger logger = Logger.getLogger(StreamGobbler.class);
InputStream is;
String type;
OutputStream os;
public StreamGobbler(InputStream is, String type) {
this(is, type, null);
}
public StreamGobbler(InputStream is, String type, OutputStream redirect) {
this.is = is;
this.type = type;
this.os = redirect;
}
public void run() {
InputStreamReader isr = null;
BufferedReader br = null;
PrintWriter pw = null;
try {
if (os != null)
pw = new PrintWriter(os);
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
String line=null;
while ( (line = br.readLine()) != null) {
if (pw != null)
pw.println(line);
logger.info(type + ">" + line);
}
if (pw != null)
pw.flush();
} catch (IOException ioe) {
ioe.printStackTrace();
} finally{
if(pw != null){
pw.close();
pw = null;
}
if(isr != null){
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
isr = null;
}
if(br != null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
br = null;
}
}
}
}
总结:当遇到问题的,不能只往一个方向钻,可以换种方式处理,总能找到适合自己的方法。

×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. :当时要执行kettle命令的时候,遇到kettle的命令符号丢失,如果是linux环境,使用如下接口:
    1. 1.1. 1. 我当时的测试环境是Windows,使用了上面的接口处理kettle命令,这个 CommandLine commandline = CommandLine.parse(shellInfo);的时候,命令还是正常的,到了处理的时候execute = exec.execute(commandline);就导致了命令符号的一些丢失,比如;=
    2. 1.2. 2. 后来想了很久,查找很多资料换了一种方式处理,不能通过转义字符来处理,为什么不换一种处理cmd命令的方式了,后来换了如下方式在windoes就可以了。
      1. 1.2.1. 我试了几个方法,后来用了最后一个:execCommand(String command)这个方法就可以了。在附上一个帮助StreamGobbler.java 如下:
    3. 1.3. 总结:当遇到问题的,不能只往一个方向钻,可以换种方式处理,总能找到适合自己的方法。
,