fix space bug

This commit is contained in:
Looly 2021-06-04 18:36:18 +08:00
parent 8f2400ed43
commit 4d7b4da46a
3 changed files with 85 additions and 29 deletions

View File

@ -3,7 +3,7 @@
-------------------------------------------------------------------------------------------------------------
# 5.6.7 (2021-06-03)
# 5.6.7 (2021-06-04)
### 🐣新特性
* 【core 】 CharSequenceUtil增加join重载issue#I3TFJ5@Gitee
@ -13,6 +13,7 @@
### 🐞Bug修复
* 【core 】 修复FileUtil.normalize去掉末尾空格问题issue#1603@Github
* 【core 】 修复CharsetDetector流关闭问题issue#1603@Github
* 【core 】 修复RuntimeUtil.exec引号内空格被切分的问题issue#I3UAYB@Gitee
-------------------------------------------------------------------------------------------------------------

View File

@ -2,6 +2,8 @@ package cn.hutool.core.util;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Console;
import cn.hutool.core.text.StrBuilder;
import java.io.File;
import java.io.IOException;
@ -9,6 +11,7 @@ import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
/**
* 系统运行时工具类用于执行系统命令的工具
@ -74,22 +77,9 @@ public class RuntimeUtil {
* @return {@link Process}
*/
public static Process exec(String... cmds) {
if (ArrayUtil.isEmpty(cmds)) {
throw new NullPointerException("Command is empty !");
}
// 单条命令的情况
if (1 == cmds.length) {
final String cmd = cmds[0];
if (StrUtil.isBlank(cmd)) {
throw new NullPointerException("Command is empty !");
}
cmds = StrUtil.splitToArray(cmd, StrUtil.C_SPACE);
}
Process process;
try {
process = new ProcessBuilder(cmds).redirectErrorStream(true).start();
process = new ProcessBuilder(handleCmds(cmds)).redirectErrorStream(true).start();
} catch (IOException e) {
throw new IORuntimeException(e);
}
@ -120,20 +110,8 @@ public class RuntimeUtil {
* @since 4.1.6
*/
public static Process exec(String[] envp, File dir, String... cmds) {
if (ArrayUtil.isEmpty(cmds)) {
throw new NullPointerException("Command is empty !");
}
// 单条命令的情况
if (1 == cmds.length) {
final String cmd = cmds[0];
if (StrUtil.isBlank(cmd)) {
throw new NullPointerException("Command is empty !");
}
cmds = StrUtil.splitToArray(cmd, StrUtil.C_SPACE);
}
try {
return Runtime.getRuntime().exec(cmds, envp, dir);
return Runtime.getRuntime().exec(handleCmds(cmds), envp, dir);
} catch (IOException e) {
throw new IORuntimeException(e);
}
@ -301,4 +279,81 @@ public class RuntimeUtil {
public static long getUsableMemory() {
return getMaxMemory() - getTotalMemory() + getFreeMemory();
}
/**
* 处理命令多行命令原样返回单行命令拆分处理
* @param cmds 命令
* @return 处理后的命令
*/
private static String[] handleCmds(String... cmds){
if (ArrayUtil.isEmpty(cmds)) {
throw new NullPointerException("Command is empty !");
}
// 单条命令的情况
if (1 == cmds.length) {
final String cmd = cmds[0];
if (StrUtil.isBlank(cmd)) {
throw new NullPointerException("Command is blank !");
}
cmds = cmdSplit(cmd);
Console.log(cmds);
}
return cmds;
}
/**
* 命令分割使用空格分割考虑双引号和单引号的情况
*
* @param cmd 命令 git commit -m 'test commit'
* @return 分割后的命令
*/
private static String[] cmdSplit(String cmd){
final List<String> cmds = new ArrayList<>();
final int length = cmd.length();
final Stack<Character> stack = new Stack<>();
boolean inWrap = false;
final StrBuilder cache = StrUtil.strBuilder();
char c;
for (int i = 0; i < length; i++) {
c = cmd.charAt(i);
switch (c){
case CharUtil.SINGLE_QUOTE:
case CharUtil.DOUBLE_QUOTES:
if(inWrap){
if(c == stack.peek()){
//结束包装
stack.pop();
inWrap = false;
}
cache.append(c);
} else{
stack.push(c);
cache.append(c);
inWrap = true;
}
break;
case CharUtil.SPACE:
if(inWrap){
// 处于包装内
cache.append(c);
} else{
cmds.add(cache.toString());
cache.reset();
}
break;
default:
cache.append(c);
break;
}
}
if(cache.hasContent()){
cmds.add(cache.toString());
}
return cmds.toArray(new String[0]);
}
}

View File

@ -29,7 +29,7 @@ public class RuntimeUtilTest {
@Test
@Ignore
public void execCmdTest2() {
String str = RuntimeUtil.execForStr("cmd /c cd C:\\Program Files (x86)");
String str = RuntimeUtil.execForStr("cmd /c", "cd \"C:\\Program Files (x86)\"", "chdir");
Console.log(str);
}