`
lee79
  • 浏览: 103271 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java执行Shell脚本超时控制

阅读更多

Java的Runtime可以执行命令行脚本,某些特定场合需要对脚本的执行时间进行控制,防止脚本某些异常情况下,一直未能正确结束,导致Java主进程挂起。本文的程序对这一过程进行了控制

 

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

 

public class CommandUtils {
    private static Logger logger = LoggerFactory.getLogger(CommandUtils.class);

    //default time out, in millseconds
    public static final int DEFAULT_TIMEOUT = 10 * 1000;
    public static final int DEFAULT_INTERVAL = 1000;

    /**
     * Executes the specified command in a separate process. The method then blocks until the process returned.
     * If an error arises during the execution or if the exeecuted process returned an non-null return code,
     * the content of the process' stderr is returned to the caller. If the execution is fine, null is returned.
     *
     * @param command String
     * @return CommandResult
     */
    public static CommandResult exec(String command) {
        long start = System.currentTimeMillis();
        long last;

        CommandResult commandResult = new CommandResult();

        try {
            Process process = Runtime.getRuntime().exec(command);
            process(process, commandResult);

            if (process != null) {
                process.destroy();
            }

            last = (System.currentTimeMillis() - start) / 1000;
            logger.info("Execute command [" + command + "], last [" + last + "] s.");

        } catch (Exception e) {
            last = (System.currentTimeMillis() - start) / 1000;
            String error = "Execute command [" + command + "] last [" + last + "] s, failed [" + e.getMessage() + "]";
            logger.error(error, e);

            commandResult.setExitValue(CommandResult.EXIT_VALUE_UNEXCEPTED);
            commandResult.setErrorOutput(error);
        }

        return commandResult;
    }

    private static void process(Process process, CommandResult commandResult) {
        BufferedReader errorReader = null;
        BufferedReader inputReader = null;

        try {
            errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            inputReader = new BufferedReader(new InputStreamReader(process.getInputStream()));

            //timeout control
            long start = System.currentTimeMillis();
            boolean processFinished = false;

            while (System.currentTimeMillis() - start < DEFAULT_TIMEOUT && !processFinished) {
                processFinished = true;
                try {
                    process.exitValue();
                } catch (IllegalThreadStateException e) {
                    // process hasn't finished yet
                    processFinished = false;

                    try {
                        Thread.sleep(DEFAULT_INTERVAL);
                    } catch (InterruptedException e1) {
                        logger.error("Process, failed [" + e.getMessage() + "]", e);
                    }
                }
            }

            if (!processFinished) {
                commandResult.setExitValue(CommandResult.EXIT_VALUE_TIMEOUT);
                commandResult.setErrorOutput("Command process timeout");
                return;
            }

            commandResult.setExitValue(process.waitFor());

            StringBuffer sb;
            String line;

            //parse error info
            if (errorReader.ready()) {
                sb = new StringBuffer();
                while ((line = errorReader.readLine()) != null) {
                    sb.append(line);
                }
                commandResult.setErrorOutput(sb.toString());
            }

            //parse info
            if (inputReader.ready()) {
                sb = new StringBuffer();
                while ((line = inputReader.readLine()) != null) {
                    sb.append(line);
                }
                commandResult.setInfoOutput(sb.toString());
            }

        } catch (Exception e) {
            String error = "Command process, failed [" + e.getMessage() + "]";
            logger.error(error, e);

            commandResult.setExitValue(CommandResult.EXIT_VALUE_UNEXCEPTED);
            commandResult.setErrorOutput(error);

        } finally {
            if (errorReader != null) {
                try {
                    errorReader.close();
                } catch (IOException e) {
                    logger.error("Close BufferedReader, failed [" + e.getMessage() + "]", e);
                }
            }

            if (inputReader != null) {
                try {
                    inputReader.close();
                } catch (IOException e) {
                    logger.error("Close BufferedReader, failed [" + e.getMessage() + "]", e);
                }
            }
        }
    }
}

 

分享到:
评论
3 楼 u013246812 2017-06-20  
谢谢博主帮我解决了问题,就是那个process.exitValue()方法是解决问题的关键,我一直没注意点这个方法的执行时抛异常表示子进程还没有执行完。
2 楼 lee79 2009-11-13  
呵呵,讲的很对
1 楼 fangwei 2009-08-17  
非常感谢!!!

btw 你虽然用到了slf4j,却没有用到它的强项
logger.info("Execute command [{}], last [{}] s.",command,last);
如果是遗留问题,可以当我废话

相关推荐

    jdbc-avail-wait:简单的Java命令行应用程序(将在shell脚本中使用),等待指定的JDBC URL(用户名和密码)可用

    一个非常简单的命令行实用程序,它可以等待直到指定的JDBC连接可以访问或等待时间超时。 动机 假设您要使用数据库(oracle)启动docker容器,同时您要使用tomcat启动另一个容器,该容器的数据源正在使用oracle容器...

    某银行用了10多年的Java-jar启停脚本(超详细).zip

    某银行用了10多年的Java启动脚本,包括运行状态检查,如果程序正在运行则杀死,杀死期间循环检查,直到杀死或者杀死超时,然后重新启动,如果程序没有运行则直接启动,启动期间每间隔一定时间检测一次,直到启动成功或者超时...

    JAVA上百实例源码以及开源项目

     Java访问权限控制,为Java操作文件、写入文件分配合适的权限,定义写到文件的信息、定义文件,输出到c:/hello.txt、写信息到文件、关闭输出流。 Java绘制图片火焰效果 1个目标文件 摘要:Java源码,图形操作,火焰...

    JAVA上百实例源码以及开源项目源代码

     Java访问权限控制,为Java操作文件、写入文件分配合适的权限,定义写到文件的信息、定义文件,输出到c:/hello.txt、写信息到文件、关闭输出流。 Java绘制图片火焰效果 1个目标文件 摘要:Java源码,图形操作,火焰...

    java开源包4

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

    java开源包101

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

    java开源包11

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

    java开源包6

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

    java开源包9

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

    java开源包5

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

    java开源包8

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

    java开源包10

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

    java开源包1

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

    java开源包3

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

    java开源包2

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

    java开源包7

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

    Java资源包01

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

    synthesis-aided-basic-block-assurance:支持综合辅助基本模块模型可靠性保证框架的工具

    要运行一些Shell脚本,需要超时工具。 一些脚本/ jar也称为和模型检查器。 建造 要构建工具集,请移至项目的根目录并运行: 蚂蚁 为了您的方便, 已经提供了内置版本。 二手综合工具 EFSM-Tools:提供了所需的jar...

    DataX Web分布式数据同步工具-其他

    任务"执行器"支持集群部署,支持执行器多节点路由策略选择,支持超时控制、失败重试、失败告警、任务依赖,执行器CPU.内存.负载的监控等等。后续还将提供更多的数据源支持、数据转换UDF、表结构同步、数据同步血缘等...

Global site tag (gtag.js) - Google Analytics