java如何執(zhí)行bat腳本,并監(jiān)控執(zhí)行結(jié)果
java執(zhí)行bat腳本,并監(jiān)控執(zhí)行結(jié)果
親測可用!
直接上工具類的代碼:
import java.io.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class NoteUtil { /** * 執(zhí)行bat腳本文件,彈出cmd黑窗 * @param command 執(zhí)行腳本文件命令 * @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){ } } /** * 執(zhí)行bat腳本,讀取cmd輸出內(nèi)容 * 注意:按行執(zhí)行的,所以需要注意腳本編寫的時候一條命令需要寫進一行中,而且還要注意執(zhí)行命令時所在的文件夾地址,如果是需要在特定文件夾下執(zhí)行的命令,則需要每行命令開始時跳轉(zhuǎn)到該目錄 * @param batPath 執(zhí)行的腳本文件絕對路徑 */ 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); //不需要彈窗,獲得命令執(zhí)行后的輸入流,打印執(zhí)行結(jié)果 System.out.println(runExecution2("D:\\application\\腳本文件絕對路徑.bat")); } }
在測試的發(fā)現(xiàn),如果彈窗來執(zhí)行bat腳本,那么java代碼中獲取到的輸入流中是空的
bat腳本使用 && 對兩條語句進行拼接,語句拼接的時候注意注釋,以免腳本都拼接到注釋后面去了導(dǎo)致執(zhí)行不到
java執(zhí)行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);
完整的調(diào)用案例:
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轉(zhuǎn)3dtiles程序開始執(zhí)行"); } else { return new HttpResponse<>("工具配置設(shè)置失敗,請檢查配置文件"); } }
方式二
下面是原生寫法,除非需要盡量減小外部依賴比如很明確不能用hutools工具,否則建議拋棄下面寫法,就用上面的就好
- controller層
/** * Copyright ? 2021. All rights reserved. * * @描述: 監(jiān)控服務(wù) * @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 * * @描述: 監(jiān)控服務(wù) * * @author: Eric * * @date: 2022年6月21日 */ @Log(value = "", name = "監(jiān)控服務(wù)") @RestController @RequestMapping(value = "/ops/monitor") public class MonitorController extends BaseController<MonitorEntity> { @Resource public MonitorService monitorService; @Override public BaseService<MonitorEntity> getBaseService() { return monitorService; } @Log(value = "獲取服務(wù)啟動狀態(tài)", name = "") @RequestMapping(value = "/list", method = RequestMethod.GET) public HttpResponsePageList<MonitorEntity> list() { return monitorService.getServerList(); } @Log(value = "獲取服務(wù)啟動日志", name = "") @RequestMapping(value = "/getLog", method = RequestMethod.GET) public HttpResponse<String> list(String serverName,String port) { return monitorService.getLog(serverName,port); } @Log(value = "啟動服務(wù)", name = "") @RequestMapping(value = "/startServer", method = RequestMethod.GET) public HttpResponse<String> startServer(String serverName,String port) { return monitorService.startServer(serverName,port); } @Log(value = "關(guān)閉服務(wù)", name = "") @RequestMapping(value = "/stopServer", method = RequestMethod.GET) public HttpResponse<String> stopServer(String serverName,String port) { return monitorService.stopServer(serverName,port); } @Log(value = "地圖服務(wù)訪問情況統(tǒng)計", 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 * @描述: 監(jiān)控服務(wù) * @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; } } }
注意一:執(zhí)行exe時不能直接start,得先cd進去,比如
cmd /c start cd E:/Work/File//路網(wǎng)計算程序 && start /d "E:/Work/File/路網(wǎng)計算程序" RdFLSim.exe
注意/d命令后面有引號將xxx.exe分開了
注意二:如果執(zhí)行exe后面還需要帶參數(shù),則注意一中的寫法無效,可以使用下面方式執(zhí)行,指定環(huán)境里面執(zhí)行exe
* Runtime.exec(String command, String[] envp, File dir) //在指定環(huán)境和工作目錄的獨立進程中執(zhí)行指定的命令和變量
//說明:參數(shù)1是需要執(zhí)行的cmd命令,不需要先cd到相關(guān)目錄了, // 參數(shù)2是 環(huán)境變量 // 參數(shù)3是執(zhí)行exe的工作目錄, Runtime.getRuntime().exec("cmd /c start osgTo3DTiles.exe -C OsgTo3DtilesConfig.json", null, new File("E:/Work/2022/clouddisk/toolbox/osgTo3Dtiles"));
方式三
需要輸入?yún)?shù)的cmd命令,比如中間需要輸入數(shù)據(jù)庫密碼
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"; }
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java 配置log4j日志文件路徑 (附-獲取當(dāng)前類路徑的多種操作)
這篇文章主要介紹了Java 配置log4j日志文件路徑 (附-獲取當(dāng)前類路徑的多種操作),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10Oracle+Mybatis的foreach insert批量插入報錯的快速解決辦法
本文給大家介紹Oracle+Mybatis的foreach insert批量插入報錯的快速解決辦法,非常不錯,具有參考借鑒價值,感興趣的朋友參考下吧2016-08-08Spring Boot分段處理List集合多線程批量插入數(shù)據(jù)的解決方案
大數(shù)據(jù)量的List集合,需要把List集合中的數(shù)據(jù)批量插入數(shù)據(jù)庫中,本文給大家介紹Spring Boot分段處理List集合多線程批量插入數(shù)據(jù)的解決方案,感興趣的朋友跟隨小編一起看看吧2024-04-04Java Swing組件布局管理器之FlowLayout(流式布局)入門教程
這篇文章主要介紹了Java Swing組件布局管理器之FlowLayout(流式布局),結(jié)合實例形式分析了Swing組件布局管理器FlowLayout流式布局的常用方法及相關(guān)使用技巧,需要的朋友可以參考下2017-11-11Java中ArrayList和LinkedList有什么區(qū)別舉例詳解
這篇文章主要介紹了Java中ArrayList和LinkedList區(qū)別的相關(guān)資料,包括數(shù)據(jù)結(jié)構(gòu)特性、核心操作性能、內(nèi)存與GC影響、擴容機制、線程安全與并發(fā)方案,以及工程實踐場景,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2025-02-02Spring Boot 通過 Mvc 擴展方便進行貨幣單位轉(zhuǎn)換的代碼詳解
這篇文章主要介紹了Spring Boot 通過 Mvc 擴展方便進行貨幣單位轉(zhuǎn)換,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12SpringCloud?集成Sentinel的實戰(zhàn)教程
這篇文章主要介紹了SpringCloud?集成Sentinel的詳細過程,本文通過實例代碼圖文相結(jié)合給大家介紹的非常詳細,感興趣的朋友一起看看吧2024-08-08Java連接SQL?Server數(shù)據(jù)庫的超詳細教程
在Java應(yīng)用程序中我們經(jīng)常需要與數(shù)據(jù)庫進行交互,一種常見的數(shù)據(jù)庫是Microsoft?SQL?Server,下面這篇文章主要給大家介紹了關(guān)于Java連接SQL?Server數(shù)據(jù)庫的超詳細教程,需要的朋友可以參考下2024-01-01