com.ideaaedi.commonds.bash.BashUtil Maven / Gradle / Ivy
The newest version!
package com.ideaaedi.commonds.bash;
import com.ideaaedi.commonds.io.IOUtil;
import lombok.extern.slf4j.Slf4j;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.nio.charset.StandardCharsets;
import java.util.Locale;
import java.util.Scanner;
/**
* bash/sh 工具类
*
* @author JustryDeng
* @since 1.0.0
*/
@Slf4j
public final class BashUtil {
public static final String PORTS_PLACEHOLDER = "ports_placeholder";
/**
* 当前操作系统是否是windows
*/
public static final boolean IS_WINDOWS = System.getProperty("os.name").toLowerCase(Locale.ENGLISH).contains("windows");
public static final String ORIGIN_KILL_PROCESS_BY_PORT_BAT = ""
+ "@echo off & setlocal EnableDelayedExpansion\n"
+ "\n"
+ "title kill process by port\n"
+ "echo;Start.\n"
+ "\n"
+ "for %%a in (" + PORTS_PLACEHOLDER + ") do (\n"
+ " set pid=0\n"
+ " for /f \"tokens=2,5\" %%b in ('netstat -ano ^| findstr \":%%a\"') do (\n"
+ " set temp=%%b\n"
+ " for /f \"usebackq delims=: tokens=1,2\" %%i in (`set temp`) do (\n"
+ " if %%j==%%a (\n"
+ " for /f \"delims=,\" %%d in ('tasklist ^| findstr \"%%c\"') do @echo;%%~d\n"
+ " taskkill /f /pid %%c\n"
+ " echo;Try to kill pid [%%c] ^(who occupy port [%%a]^) completed.\n"
+ " )\n"
+ " )\n"
+ " )\n"
+ ")\n"
+ "\n"
+ "echo;Done.\n";
/**
* 运行命令
*
* @param cmd
* 命令
* @return 结果
*/
public static String runBash(String cmd) {
return runBash(cmd, 0);
}
/**
* 运行命令
*
* @param bash
* 命令
* @param line
* 返回第几行结果,<=0,则返回所有
* @return 结果
*/
public static String runBash(String bash, int line) {
// 直接执行命令行指令,记录warn
log.warn("You are running bash -> " + bash + ", line -> " + line);
if (bash == null || bash.length() == 0) {
throw new RuntimeException("bash cannot be empty.");
}
Process process;
Scanner sc = null;
StringBuilder sb = new StringBuilder();
try {
process = Runtime.getRuntime().exec(bash);
process.getOutputStream().close();
sc = new Scanner(process.getInputStream(), IS_WINDOWS ? "GBK" : StandardCharsets.UTF_8.name());
int i = 0;
while (sc.hasNextLine()) {
i++;
String str = sc.nextLine();
if (line <= 0) {
sb.append(str).append(System.lineSeparator());
} else if (i == line) {
return str.trim();
}
}
return sb.toString();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
IOUtil.close(sc);
}
}
/**
* 运行命令并输出到控制台
*
* @param bash
* 命令
*/
public static void runBashAndPrint(String bash) {
// 代码直接调用执行命令行指令是不被推荐的,记录warn
log.warn("You are running bash -> " + bash);
if (bash == null || bash.length() == 0) {
throw new RuntimeException("bash cannot be empty.");
}
Process process;
Scanner sc = null;
try {
process = Runtime.getRuntime().exec(bash);
process.getOutputStream().close();
sc = new Scanner(process.getInputStream(), IS_WINDOWS ? "GBK" : StandardCharsets.UTF_8.name());
while (sc.hasNextLine()) {
System.out.println(sc.nextLine());
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
IOUtil.close(sc);
}
}
/**
* 要执行的bat文件内容
*
* only for windows
*
*/
public static String killProcessByPorts(String... port) {
if (port == null || port.length == 0) {
return "";
}
String batContent = ORIGIN_KILL_PROCESS_BY_PORT_BAT.replace(PORTS_PLACEHOLDER, String.join(",", port));
Process process = null;
InputStream inputStream = null;
BufferedReader bufferedReader = null;
StringBuilder sb = new StringBuilder(64);
try {
File tmpBatFile = new File("/tmp/tmp_" + System.currentTimeMillis() + ".bat");
IOUtil.writeContentToFile(batContent, tmpBatFile);
process = Runtime.getRuntime().exec(tmpBatFile.getAbsolutePath());
inputStream = process.getInputStream();
bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "GBK"));
String line;
while ((line = bufferedReader.readLine()) != null) {
line = line.trim();
if (sb.toString().equals("Start.\n")) {
sb.append("------\n");
}
sb.append(line).append("\n");
if (line.startsWith("Try to kill pid")) {
sb.append("------\n");
}
}
IOUtil.delete(tmpBatFile);
}catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (process != null) {
try {
process.waitFor();
} catch (Exception e) {
// ignore
}
}
IOUtil.close(inputStream, bufferedReader);
if (process != null) {
try {
process.destroy();
} catch (Exception e) {
// ignore
}
}
}
return sb.toString();
}
/**
* 获取当前进程pid
*
* @return 当前进程的ID
*/
public static String currPid() {
// 获取当前JVM进程的进程id
RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
String name = runtime.getName(); // format: "pid@hostname"
String[] infoArr = name.split("@");
if (infoArr.length == 0) {
// 获取进程失败
throw new IllegalStateException("determine pid fail, determined name is " + name);
}
return infoArr[0];
}
}