java如何执行bat脚本,并监控执行结果
作者:可乐加可乐冰
这篇文章主要介绍了java如何执行bat脚本,并监控执行结果问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
java执行bat脚本,并监控执行结果
亲测可用!
直接上工具类的代码:
import java.io.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class NoteUtil { /** * 执行bat脚本文件,弹出cmd黑窗 * @param command 执行脚本文件命令 * @param navigatePath 脚本文件所在文件夹地址 */ public static void runExecution(List<String> command, File navigatePath) { System.out.println(command); ProcessBuilder executeProcess=new ProcessBuilder(command); executeProcess.directory(navigatePath); try { Process resultExecution = executeProcess.start(); }catch (Exception e){ } } /** * 执行bat脚本,读取cmd输出内容 * 注意:按行执行的,所以需要注意脚本编写的时候一条命令需要写进一行中,而且还要注意执行命令时所在的文件夹地址,如果是需要在特定文件夹下执行的命令,则需要每行命令开始时跳转到该目录 * @param batPath 执行的脚本文件绝对路径 */ public static Map<String, String> runExecution2(String batPath) { StringBuffer sb1 = new StringBuffer(); StringBuffer sb2 = new StringBuffer(); try { BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(batPath), "UTF-8"));//读取脚本 String line; List<String> batList = new ArrayList(); while ((line = br.readLine()) != null) { if (!line.equals("")) { batList.add(line); } } for (String command : batList) { Process pro = Runtime.getRuntime().exec("cmd /c " + command); BufferedReader br1 = new BufferedReader(new InputStreamReader(pro.getInputStream(), "GBK")); BufferedReader br2 = new BufferedReader(new InputStreamReader(pro.getErrorStream(), "GBK")); System.out.println("Input Stream:"); while ((line = br1.readLine()) != null) { System.out.println(line); sb1.append(line).append(System.getProperty("line.separator")); } System.out.println("Error Stream:"); while ((line = br2.readLine()) != null) { System.out.println(line); sb2.append(line).append(System.getProperty("line.separator")); } } } catch (IOException e) { e.printStackTrace(); } finally { Map map = new HashMap(); map.put("getInputStreamString", sb1.toString()); map.put("getErrorStreamString", sb2.toString()); return map; } } public static void main(String[] args) { //cmd弹窗 File jsFile=new File("D:\\application\\bat文件所在的目录"); String cmdPrompt="cmd"; String type="/c"; String start = "start"; String bat="run.bat"; List<String> updateCommand=new ArrayList<String>(); updateCommand.add(cmdPrompt); updateCommand.add(type); updateCommand.add(start); updateCommand.add(bat); runExecution(updateCommand,jsFile); //不需要弹窗,获得命令执行后的输入流,打印执行结果 System.out.println(runExecution2("D:\\application\\脚本文件绝对路径.bat")); } }
在测试的发现,如果弹窗来执行bat脚本,那么java代码中获取到的输入流中是空的
bat脚本使用 && 对两条语句进行拼接,语句拼接的时候注意注释,以免脚本都拼接到注释后面去了导致执行不到
java执行bat、exe等cmd命令
方式一
建议使用hutool-all.jar,它对Runtime.getRuntime()做了完美的封装
String cmdStr = new StringBuffer("cmd /c osgTo3DTiles.exe -C OsgTo3DtilesConfig.json").toString(); Process exec = RuntimeUtil.exec(null,new File(CLOUDDISK_TOOLBOX),cmdStr); String result = RuntimeUtil.getResult(exec, io.netty.util.CharsetUtil.UTF_8); String errorResult = RuntimeUtil.getErrorResult(exec, io.netty.util.CharsetUtil.UTF_8);
完整的调用案例:
public HttpResponse<String> objto3dtiles(ObjTo3dtilesVo objto3dtilesVo) { //检测工具是否存在 if (!FileUtil.exist(CLOUDDISK_TOOLBOX + "/osgTo3DTiles.exe")) { return new HttpResponse<>("工具不存在,检查路径"); } //配置文件是否存在 if (!FileUtil.exist(CLOUDDISK_TOOLBOX + "/OsgTo3DtilesConfig.json")) { return new HttpResponse<>("工具配置文件不存在,检查路径"); } //读取配置文件 OsgTo3DtilesConfig.json JSONObject config = JSONObject.parseObject(FileUtil.readString(CLOUDDISK_TOOLBOX + "/OsgTo3DtilesConfig.json", CharsetUtil.UTF_8)); if (config.replace("osgRootDir", config.getString("osgRootDir"), objto3dtilesVo.getSourceFile()) && config.replace("tileRootDir", config.getString("tileRootDir"), objto3dtilesVo.getTartgetFile())) { FileUtil.writeUtf8String(config.toJSONString(), CLOUDDISK_TOOLBOX + "/OsgTo3DtilesConfig.json"); String cmdStr = new StringBuffer("cmd /c osgTo3DTiles.exe -C OsgTo3DtilesConfig.json").toString(); ToolBoxTask toolBoxTask = new ToolBoxTask(); toolBoxTask.setCreator(objto3dtilesVo.getCreator()); toolBoxTask.setCreatorId(objto3dtilesVo.getCreatorId()); toolBoxTask.setStatus(2); toolBoxTask.setType(1); toolBoxTask.setTaskName("osgTo3DTiles_" + System.currentTimeMillis()); ToolBoxTask save = toolBoxDao.save(toolBoxTask); new Thread(()->{ Process exec = RuntimeUtil.exec(null,new File(CLOUDDISK_TOOLBOX),cmdStr); String result = RuntimeUtil.getResult(exec, io.netty.util.CharsetUtil.UTF_8); String errorResult = RuntimeUtil.getErrorResult(exec, io.netty.util.CharsetUtil.UTF_8); save.setResult(result); save.setRemark(errorResult); save.setStatus(10); toolBoxDao.save(save); }).start(); return new HttpResponse<>("osbj转3dtiles程序开始执行"); } else { return new HttpResponse<>("工具配置设置失败,请检查配置文件"); } }
方式二
下面是原生写法,除非需要尽量减小外部依赖比如很明确不能用hutools工具,否则建议抛弃下面写法,就用上面的就好
- controller层
/** * Copyright © 2021. All rights reserved. * * @描述: 监控服务 * @Prject: DataHub * @Package: com.domain.module.ops.message.controller * @ClassName: MonitorController * @date: 2022年6月21日 * @version: V1.0 */ package com.domain.module.ops.monitor.controller; import com.domain.common.aop.Log; import com.domain.common.response.HttpResponse; import com.domain.common.response.HttpResponsePageList; import com.domain.framework.controller.BaseController; import com.domain.framework.service.BaseService; import com.domain.module.ops.monitor.entity.MonitorEntity; import com.domain.module.ops.monitor.service.MonitorService; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; /** * @ClassName: MonitorController * * @描述: 监控服务 * * @author: Eric * * @date: 2022年6月21日 */ @Log(value = "", name = "监控服务") @RestController @RequestMapping(value = "/ops/monitor") public class MonitorController extends BaseController<MonitorEntity> { @Resource public MonitorService monitorService; @Override public BaseService<MonitorEntity> getBaseService() { return monitorService; } @Log(value = "获取服务启动状态", name = "") @RequestMapping(value = "/list", method = RequestMethod.GET) public HttpResponsePageList<MonitorEntity> list() { return monitorService.getServerList(); } @Log(value = "获取服务启动日志", name = "") @RequestMapping(value = "/getLog", method = RequestMethod.GET) public HttpResponse<String> list(String serverName,String port) { return monitorService.getLog(serverName,port); } @Log(value = "启动服务", name = "") @RequestMapping(value = "/startServer", method = RequestMethod.GET) public HttpResponse<String> startServer(String serverName,String port) { return monitorService.startServer(serverName,port); } @Log(value = "关闭服务", name = "") @RequestMapping(value = "/stopServer", method = RequestMethod.GET) public HttpResponse<String> stopServer(String serverName,String port) { return monitorService.stopServer(serverName,port); } @Log(value = "地图服务访问情况统计", name = "") @RequestMapping(value = "/statisticServiceType", method = RequestMethod.GET) public HttpResponse<String> statisticServiceType() { return monitorService.statisticServiceType(); } }
- service层
/** * Copyright © 2021. All rights reserved. * * @描述: 消息中心 * @Prject: DataHub * @Package: com.domain.module.ops.message.service * @ClassName: OpinionServiceImpl * @author: Eric * @date: 2022年6月6日 * @version: V1.0 */ package com.domain.module.ops.monitor.service; import com.alibaba.fastjson.JSONObject; import com.domain.common.response.HttpResponse; import com.domain.common.response.HttpResponsePageList; import com.domain.common.response.PageList; import com.domain.framework.dao.BaseDao; import com.domain.framework.service.BaseServiceImpl; import com.domain.module.ops.monitor.dao.MonitorDao; import com.domain.module.ops.monitor.entity.MonitorEntity; import com.domain.module.res.registerresources.service.RegisterResourcesService; import com.domain.module.store.file.dao.FileDao; import org.elasticsearch.index.query.QueryBuilders; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.io.*; import java.nio.charset.Charset; import java.time.LocalDate; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; /** * @ClassName: MonitorServiceImpl * @描述: 监控服务 * @author: Eric * @date: 2022年5月16日 */ @Service public class MonitorServiceImpl extends BaseServiceImpl<MonitorEntity> implements MonitorService { @Resource public MonitorDao monitorDao; @Value("${nginx.logsUrl}") public String NGINX_LOG_URL; @Resource public RegisterResourcesService registerResourcesService; @Autowired FileDao fileDao; @Resource org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate template; private static String readFile(File file) { List<String> list = new ArrayList<>(); try { InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "gbk"); BufferedReader bw = new BufferedReader(isr); String line = null; while ((line = bw.readLine()) != null) { list.add(line); } bw.close(); } catch (IOException e) { e.printStackTrace(); } StringBuffer text = new StringBuffer(); for (int i = 0; i < list.size(); i++) { String[] st = list.get(i).split("\t"); for (int j = 0; j < st.length; j++) { text.append(st[j]); } } return text.toString(); } @Override public BaseDao<MonitorEntity> getBaseDao() { return monitorDao; } @Override public HttpResponsePageList<MonitorEntity> getServerList() { String baseUrlStr = NGINX_LOG_URL + "bat_logs"; try { File[] serverList = new File(baseUrlStr).listFiles(); if (serverList != null || serverList.length > 0) { Stream<File> fileStream = Stream.of(serverList); List<MonitorEntity> MonitorList = fileStream.map(n -> { String nameStr = n.getName(); boolean contains = nameStr.contains("-"); String sName = ""; String sPort = ""; Boolean sStatus = false; StringBuffer cmdStr = new StringBuffer(); if (contains) { String[] splitName = nameStr.split("-"); sName = splitName[0]; sPort = splitName[1].replace(".log", ""); cmdStr.append("cmd /c netstat -aon|findstr ").append(sPort); } else { sName = nameStr.replace(".log", ""); cmdStr.append("tasklist /fi \"imagename eq " + sName + ".exe\""); } String result = startBatShell(cmdStr.toString()); sStatus = (result == null || result.equals("") || result.contains("信息")) ? false : true; String fileContext = readFile(n); return new MonitorEntity(sName, sPort, sStatus, fileContext); }).collect(Collectors.toList()); return new HttpResponsePageList<MonitorEntity>(new PageList<>(MonitorList)); } } catch (Exception e) { e.printStackTrace(); } return new HttpResponsePageList<MonitorEntity>(); } @Override public HttpResponse<String> getLog(String serverName, String port) { String baseUrlStr = NGINX_LOG_URL.split("/DMS/")[0] + "/DMS/"; switch (serverName) { case "nginx": baseUrlStr += "online_datahub/logs/"; String index = "access-" + LocalDate.now().toString(); //access-2022-06-23 File nginxLog = new File(baseUrlStr + index + ".log"); if (nginxLog.exists()) { String readFile = readFile(nginxLog); serverName = readFile; } break; case "mapserver": baseUrlStr += "service_engine/mapserver/log/app.log"; serverName = readLog(baseUrlStr); break; case "rasterserver": baseUrlStr += "service_engine/rasterserver/log/app.log"; serverName = readLog(baseUrlStr); break; case "elasticsearch": baseUrlStr += "system_plugins/elasticsearch/logs/elasticsearch.log"; serverName = readLog(baseUrlStr); break; case "server_controller": baseUrlStr += "server_controller/logs/"; String scIndex = "catalina." + LocalDate.now().toString(); File scLog = new File(baseUrlStr + scIndex + ".log"); if (scLog.exists()) { String readFile = readFile(scLog); serverName = readFile; } break; default: String path = (port == null || "".equals(port)) ? NGINX_LOG_URL + "bat_logs/" + serverName + ".log" : NGINX_LOG_URL + "bat_logs/" + serverName + "-" + port + ".log"; File batLog = new File(path); if (batLog.exists()) { String readFile = readFile(batLog); serverName = readFile; } break; } return new HttpResponse<>(serverName); } @Override public HttpResponse<String> stopServer(String serverName, String port) { String os = System.getProperty("os.name").toLowerCase(); String cmdStr = ""; if (os.contains("windows")) { if (port.equals("") || null == port) { cmdStr = "taskkill /f /t /im " + serverName + ".exe"; } else { String getPidStr = "netstat -ano|findstr " + port; String startBatShell = startBatShell(getPidStr); if (startBatShell.length() > 0) { BufferedReader br = new BufferedReader(new InputStreamReader( new ByteArrayInputStream(startBatShell.getBytes(Charset.forName("utf8"))), Charset.forName("utf8"))); String readLine = null; try { readLine = br.readLine(); if (readLine != null && readLine.contains("LISTENING")) { String pidStr = readLine.split("LISTENING")[1].trim(); cmdStr = "taskkill /pid " + pidStr + " /f"; } } catch (IOException e) { e.printStackTrace(); } } } startBatShell(cmdStr); } return new HttpResponse<>(serverName + "已停止"); } @Override public HttpResponse<String> startServer(String serverName, String port) { String baseUrlStr = NGINX_LOG_URL.split("/DMS/")[0] + "/DMS/"; switch (serverName) { case "mapserver": case "rasterserver": baseUrlStr += "service_engine/" + serverName + "/"; startBatShell("cmd /c start cd " + baseUrlStr + " && start /d \"" + baseUrlStr + "\" " + serverName + ".exe"); break; case "online_datahub": baseUrlStr += "online_datahub/"; startBatShell("cmd /c start " + baseUrlStr + "server.bat"); break; case "server_controller": baseUrlStr += "server_controller/bin/startup.bat"; startBatShell("cmd /c start " + baseUrlStr); break; case "server_manager": baseUrlStr += "service_engine/server-manager/"; startBatShell("cmd /c start " + baseUrlStr + "server.bat"); break; } return new HttpResponse<>(serverName + "已启动"); } @Override public HttpResponse<String> statisticServiceType() { IndexCoordinates index = IndexCoordinates.of("filebeat-log*"); NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder(); builder.withQuery(QueryBuilders.boolQuery()); builder.withFields("message", "@timestamp"); NativeSearchQuery searchQuery = builder.build(); SearchHits<JSONObject> scroll = template.search(searchQuery, JSONObject.class, index); Iterator<SearchHit<JSONObject>> iterator = scroll.iterator(); Long rasterTotal = 0L; Long mapTotal = 0L; Long rasterDate = 0L; Long mapDate = 0L; String tempMapDate = ""; String tempRasterDate = ""; ArrayList<Map> mapList = new ArrayList<>(); ArrayList<Map> rasterList = new ArrayList<>(); ArrayList<Map> shareList = new ArrayList<>(); while (iterator.hasNext()) { JSONObject content = iterator.next().getContent(); String message = content.getString("message"); String date = content.getString("@timestamp").split("T")[0]; if (message.contains("/mapserver/")) { mapTotal++; if (date.equals(tempMapDate) || tempMapDate.equals("")) { tempMapDate = date; mapDate++; } else { Map<String, Object> map = new HashMap<>(); map.put("mapDate", tempMapDate); map.put("mapValue", mapDate); mapList.add(map); mapDate = 0L; tempMapDate = date; } } else if (message.contains("/rasterserver/")) { rasterTotal++; if (date.equals(tempRasterDate) || tempRasterDate.equals("")) { tempRasterDate = date; rasterDate++; } else { Map<String, Object> map = new HashMap<>(); map.put("rasterDate", tempRasterDate); map.put("rasterValue", rasterDate); rasterList.add(map); rasterDate = 0L; tempRasterDate = date; } } } Map<String, Object> map = new HashMap<>(); map.put("mapDate", tempMapDate); map.put("mapValue", mapDate); mapList.add(map); map = new HashMap<>(); map.put("rasterDate", tempRasterDate); map.put("rasterValue", rasterDate); rasterList.add(map); Map<String, Object> res = new HashMap<>(); res.put("mapTotal", mapTotal); res.put("rasterTotal", rasterTotal); res.put("mapDateCount", mapList); res.put("rasterDateCount", rasterList); List<Object[]> objects = fileDao.countFileType(); res.put("storeFile", objects); List<Map<String, Object>> downloadList = registerResourcesService.resourceDownLoadCount(); res.put("download", downloadList); Map<String, Object> shareType = registerResourcesService.registerCount(); res.put("shareType", shareType); return new HttpResponse<>(JSONObject.toJSONString(res)); } private String readLog(String baseUrlStr) { String log = ""; File file = new File(baseUrlStr); if (file.exists()) { log = readFile(file); } return log; } String startBatShell(String cmd) { try { Process psServe = Runtime.getRuntime().exec(cmd); psServe.waitFor(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(psServe.getInputStream(), "gbk")); String line = null; StringBuilder sb = new StringBuilder(); while ((line = bufferedReader.readLine()) != null) { sb.append(line + "\n"); } return sb.toString(); } catch (Exception e) { e.printStackTrace(); return null; } } }
注意一:执行exe时不能直接start,得先cd进去,比如
cmd /c start cd E:/Work/File//路网计算程序 && start /d "E:/Work/File/路网计算程序" RdFLSim.exe
注意/d命令后面有引号将xxx.exe分开了
注意二:如果执行exe后面还需要带参数,则注意一中的写法无效,可以使用下面方式执行,指定环境里面执行exe
* Runtime.exec(String command, String[] envp, File dir) //在指定环境和工作目录的独立进程中执行指定的命令和变量
//说明:参数1是需要执行的cmd命令,不需要先cd到相关目录了, // 参数2是 环境变量 // 参数3是执行exe的工作目录, Runtime.getRuntime().exec("cmd /c start osgTo3DTiles.exe -C OsgTo3DtilesConfig.json", null, new File("E:/Work/2022/clouddisk/toolbox/osgTo3Dtiles"));
方式三
需要输入参数的cmd命令,比如中间需要输入数据库密码
public static String ExecuteCmd(String cmdsql,String directorypath,Map<String, String> envMap) throws Exception { ProcessBuilder builder = new ProcessBuilder(); if (isWindows) { //cmdsql = " pg_dump -h localhost -p 5432 -U postgres -d platform -t shapefile_d644d48_1553046876115 -f F:/1234/testshp/bbb/tb_news60.sql" builder.command("cmd.exe", "/c",cmdsql); } else { builder.command("sh", "-c", cmdsql); } //directorypath = "D:/Program Files/PostgreSQL/14/bin/" builder.directory(new File(directorypath)); Map<String, String> env = builder.environment(); //env.putAll(envMap); env.put("PGPASSWORD", "qQq314159@26"); Process process = null; try { process = builder.start(); } catch (IOException e) { e.printStackTrace(); } StreamGobbler streamGobbler = new StreamGobbler(process.getInputStream(), System.out::println); Executors.newSingleThreadExecutor().submit(streamGobbler); int exitCode = process.waitFor(); switch (exitCode){ case 0: return "ok"; case 1: return "error"; } return "ok"; }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。