java项目-ProcessBuilder执行命令或者调用脚本

41 篇文章 0 订阅

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;
    }
}

 当使用接口status参数时 最终执行的命令为  ./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": []
}

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用JavaProcessBuilder类来远程调用shell脚本ProcessBuilder类允许您启动并控制外部进程。以下是一个示例代码,它使用ProcessBuilder类从远程服务器上运行shell脚本。 ``` import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class RemoteShellExecutor { public static void main(String[] args) throws IOException, InterruptedException { String host = "remote-host"; // 远程服务器IP地址或域名 String user = "remote-user"; // 远程服务器用户名 String password = "remote-password"; // 远程服务器密码 String command = "/path/to/remote/script.sh"; // 远程服务器上的shell脚本路径 // 创建ProcessBuilder对象 ProcessBuilder processBuilder = new ProcessBuilder(); // 设置远程SSH连接命令 processBuilder.command("sshpass", "-p", password, "ssh", user + "@" + host, command); // 启动进程 Process process = processBuilder.start(); // 读取进程输出 BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } // 等待进程结束 int exitCode = process.waitFor(); System.out.println("Process exited with code " + exitCode); } } ``` 在上面的示例代码中,我们使用ProcessBuilder类创建了一个SSH连接命令,并将其设置为要执行的命令。然后,我们启动进程,并使用一个缓冲读取器来读取进程输出。最后,我们等待进程结束,并打印进程退出代码。请注意,您需要在本地计算机上安装sshpass软件包,以便使用密码连接到远程服务器。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值