ProcessBuilder执行命令或者调用脚本
主要方法
构造方法 :
ProcessBuilder(List<String> command) :利用指定的操作系统程序和参数构造一个进程生成器。
ProcessBuilder(String… command) :利用指定的操作系统程序和参数构造一个进程生成器。
方法 :
start():使用此进程生成器的属性启动一个新进程。
command() : 返回此进程生成器的操作系统程序和参数。
command(List<String> command) :设置此进程生成器的操作系统程序和参数。
command(String… command) :设置此进程生成器的操作系统程序和参数。
directory() :返回此进程生成器的工作目录。
directory(File directory) :设置此进程生成器的工作目录。
environment() :返回此进程生成器环境的字符串映射视图。 environment方法获得运行进程的环境变量,得到一个Map,可以修改环境变量
redirectErrorStream() :返回进程生成器是否合并标准错误和标准输出;true为合并,false为不合并
redirectErrorStream(boolean redirectErrorStream) :设置此进程生成器的 redirectErrorStream 属性。默认值为false不合并
Process 获取执行结果
概述
Process类是一个抽象类(所有的方法均是抽象的),封装了一个进程(即一个执行程序)。
Process 类提供了执行从进程输入、执行输出到进程、等待进程完成、检查进程的退出状态以及销毁(杀掉)进程的方法。
ProcessBuilder.start() 和 Runtime.exec 方法创建一个本机进程,并返回 Process 子类的一个实例,该实例可用来控制进程并获取相关信息。创建的子进程没有自己的终端或控制台。它的所有标准 io(即 stdin,stdout,stderr)操作都将通过三个流 (getOutputStream(),getInputStream(),getErrorStream()) 重定向到父进程,通过流的形式进行读取。
主要方法
destroy():杀掉子进程。
exitValue():返回子进程的出: 获得子进程的错误流。
InputStream getInputStream() :获得子进程的输入流。
OutputStream getOutputStream() :获得子进程的输出流。
waitFor() :导致当前线程等待,如果必要,一直要等到由该 Process 对象表示的进程已经终止
注意:
1.destroy()杀掉子线程的状态在五分钟后进程才会消失
2.执行linux命令,若命令包含一些特殊字符,需要封装ProcessBuilder 来获取Process对象.
实现逻辑
我的脚本文件是service。路径是在项目路径下的bin目录中。
public class ShellExecutor {
private static final Logger LOGGER = LoggerFactory.getLogger(ShellExecutor.class);
public static Map<String, List<String>> executeScript(String command){
Map<String, List<String>> listMap = new HashMap<>();
String filePath = System.getProperty("user.dir") + File.separator + "bin";
LOGGER.info("file path:" + filePath);
String fileCommand = "./service";
List<String> commands = Lists.newArrayList(fileCommand, command);
ProcessBuilder processBuilder = new ProcessBuilder();
File file = new File(filePath);
if(!file.exists()){
LOGGER.error("file:[" + filePath + "] not exist!");
return listMap;
}
processBuilder.directory(file);
processBuilder.command(commands);
BufferedReader inputReader = null;
BufferedReader errorReader = null;
List<String> returnString = Lists.newArrayList();
List<String> errorString = Lists.newArrayList();
listMap.put("normal", returnString);
listMap.put("error", errorString);
try {
Process process = processBuilder.start();
//脚本执行输出信息
inputReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String str = null;
while((str = inputReader.readLine()) != null){
returnString.add(str);
}
//脚本执行异常时的输出信息
errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String error = null;
while((error = inputReader.readLine()) != null){
returnString.add(error);
}
try {
if (0 != process.waitFor()) {
throw new Exception(String.format("execute [%s] fail!(%s)", String.join(" ", commands), errorString));
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (inputReader != null) {
inputReader.close();
}
if (errorReader != null) {
errorReader.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
LOGGER.info("normal return:" + ObjectUtil.convertBeanToJsonString(returnString));
LOGGER.info("error return:" + ObjectUtil.convertBeanToJsonString(errorString));
return listMap;
}
}
./service status
输出结果是:
{
"normal": [
"service name: springbootdemo",
"root 12862 12849 0 16:35 ? 00:00:00 grep springbootdemo",
"root 54842 1 0 16:26 ? 00:00:00 jsvc.exec -Dspringbootdemo -home /opt/hikvision/web/components/jre18linux64.1 -cwd /home/hik/app/springbootdemo -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=10086 -Djava.net.preferIPv4Stack=true -Dcom.sun.jndi.ldap.connect.pool.protocol=plain ssl -XX:MetaspaceSize=50M -XX:MaxMetaspaceSize=100M -Xms100M -Xmx200M -Xmn50M -XX:SurvivorRatio=8 -XX:NewRatio=3 -XX:+UseG1GC -XX:+PrintTenuringDistribution -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintAdaptiveSizePolicy -XX:+PrintHeapAtGC -XX:+DisableExplicitGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:/home/hik/app/springbootdemo/logs/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=8M -Djava.io.tmpdir=/home/hik/app/springbootdemo/temp -Dloader.path=/home/hik/app/springbootdemo/lib/* -Dloader.main=zhong.test.springbootdemo.usultestdemo.UsulTestStartApplication -wait 60 -pidfile /home/hik/app/springbootdemo/temp/springbootdemo.pid -outfile /home/hik/app/springbootdemo/logs/springbootdemo.log -errfile /home/hik/app/springbootdemo/logs/Jsvc.log -cp .:/opt/hikvision/web/components/jre18linux64.1/lib/dt.jar:/opt/hikvision/web/components/jre18linux64.1/lib/tools.jar:/home/hik/app/springbootdemo/config:/home/hik/app/springbootdemo/lib/* zhong.test.springbootdemo.usultestdemo.JsvcLauncher",
"root 54843 54842 9 16:26 ? 00:00:52 jsvc.exec -Dspringbootdemo -home /opt/hikvision/web/components/jre18linux64.1 -cwd /home/hik/app/springbootdemo -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=10086 -Djava.net.preferIPv4Stack=true -Dcom.sun.jndi.ldap.connect.pool.protocol=plain ssl -XX:MetaspaceSize=50M -XX:MaxMetaspaceSize=100M -Xms100M -Xmx200M -Xmn50M -XX:SurvivorRatio=8 -XX:NewRatio=3 -XX:+UseG1GC -XX:+PrintTenuringDistribution -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintAdaptiveSizePolicy -XX:+PrintHeapAtGC -XX:+DisableExplicitGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:/home/hik/app/springbootdemo/logs/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=8M -Djava.io.tmpdir=/home/hik/app/springbootdemo/temp -Dloader.path=/home/hik/app/springbootdemo/lib/* -Dloader.main=zhong.test.springbootdemo.usultestdemo.UsulTestStartApplication -wait 60 -pidfile /home/hik/app/springbootdemo/temp/springbootdemo.pid -outfile /home/hik/app/springbootdemo/logs/springbootdemo.log -errfile /home/hik/app/springbootdemo/logs/Jsvc.log -cp .:/opt/hikvision/web/components/jre18linux64.1/lib/dt.jar:/opt/hikvision/web/components/jre18linux64.1/lib/tools.jar:/home/hik/app/springbootdemo/config:/home/hik/app/springbootdemo/lib/* zhong.test.springbootdemo.usultestdemo.JsvcLauncher"
],
"error": []
}