JAVA调用linux命令、脚本,获取返回值

  • 定义工具类
  • 使用
  • 时间工具类
  • 总结


定义工具类

public class CommandUtils{
	/**
	* command 要执行的文件或命令   call回调函数
	**/
	public static void exec(String command,ICommandCall call){
		try{
			if(StringUtils.isEmpty(command)){
				log.error("没有要执行的命令。。");
				return;
			}
			StringBuffer cmd = new StringBuffer();
			//获取操作系统标识
			String osName = System.getProperty(os.name);
			if(os.startsWith(Window)){
				//window实现(应用比较少 不展示具体内容)
			}else if(osName.equals("Linux")){
				//linux实现
				cmd.append("sh ");
				cmd.append(command);
				cmd.append(" &");
			}
			String cmds = cmd.toString();
			log.info("启动执行:"+cmds);
			Process process = Runtime.getRuntime().exec(cmds);
			printMessage(process.getInputStream(),call);
			int waitFor = process.waitFor();
			log.info("waitFor:"+waitFor);
			process.destroy();
		}catch(Exception e){
			log.error(e.getMessage(),e);
		}
    }

	//读取输入流方法 
	static void printMessage(final InputStream inputStream,ICommand call){
		Thread thread = new Thread(new Runnable(){
			@override
			public void run(){
				try{
					//获取当前时间点
					Instant start = DateUtils.instant();
					Reader reader = new InputSteamReader(inputSteam);
					BufferedReader bufferedReader = new BufferedReader(reader);
					String line = "";
					while((line = befferedReader.readLine()) != null){
						log.info(line);
						//获取两分钟之后的时间点
						Long durationMinutes = DateUtils.getDurationMinues(start,DateUtils.minute);
						//判断当前时间点是否大于两分钟
						if(durationMinutes == Long.valueOf(2)){
							log.info("调用超时。。");
							break;
						}else{
							//执行调用逻辑
							if(StringUtils.contains(line,"stop success")){
								//接受到返回值命令退出 并处理相对应的业务逻辑
								break;					  	
							}
						}
					} 
					if(call != null){
					 	//如果定义了回调函数 执行
						call.call();
					}
					//关闭流
					bufferedReader.close();
				}catch(){
					log.error("异常:"+e.getMessage());
				}
			}
		});
		thread.start();
		thread.join();  //阻塞主线程 等待主线程执行完
	}
}

注意: 定义工具类时可根据自身需要,是否选择处理多线程问题,是否需要返回值决定回调函数进行哪些封装需要,一定要设置超时时间避免线程无法退出!

使用

public void test(){
	Thread t = new Thread(()->{
		//以linux路径 为例,启动某个tomcat服务
		CommandUtils.exec("/data/test/start.sh",null);
	});
	t.start();
	t.join();
}

通过线程触发不影响方法整体返回值,对子线程进行阻塞,如果超时子线程也会进行退出,不影响上层方法的调用。

时间工具类

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
import org.apache.commons.lang3.StringUtils;

public class DateUtils {

	public static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
	public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
	public static final SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	public static final String minute = "Minute";
	public static final String millis = "Millis";
	public static final String hours = "Hours";

	public static void main(String[] args) {
		SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dt1 = getCurrentLocalDateTime().format(DATETIME_FORMATTER);
		try {
			Thread.sleep(5000);
			String dt2 = getCurrentLocalDateTime().format(DATETIME_FORMATTER);
			Instant start = sd.parse(dt1).toInstant();
			Instant end = sd.parse(dt2).toInstant();
			System.out.println(durationMinutes(start, end) == Long.valueOf(1));
			long durationMillis = durationMillis(start, end);
			System.out.println(durationMillis);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

    //获取当前时间转换为Instant类型
	public static Instant instant() throws ParseException {
		String dt = getCurrentLocalDateTime().format(DATETIME_FORMATTER);
		return sd.parse(dt).toInstant();
	}

	public static Long getDurationMinutes(Instant start, String type) throws ParseException {
		Instant end = instant();
		Long duration = null;
		if (StringUtils.equals(minute, type)) {
			duration = DateUtils.durationMinutes(start, end);
		} else if (StringUtils.equals(millis, type)) {
			duration = DateUtils.durationMillis(start, end);
		}
		return duration;
	}

	/**
	 * 返回当前的日期
	 *
	 * @return
	 */
	public static LocalDate getCurrentLocalDate() {
		return LocalDate.now();
	}

	/**
	 * 返回当前日期时间
	 *
	 * @return
	 */
	public static LocalDateTime getCurrentLocalDateTime() {
		return LocalDateTime.now();
	}

	/**
	 * 返回当前日期字符串 yyyyMMdd
	 *
	 * @return
	 */
	public static String getCurrentDateStr() {
		return LocalDate.now().format(DATE_FORMATTER);
	}

	/**
	 * 返回当前日期时间字符串 yyyyMMddHHmmss
	 *
	 * @return
	 */
	public static String getCurrentDateTimeStr() {
		return LocalDateTime.now().format(DATETIME_FORMATTER);
	}

	public static LocalDate parseLocalDate(String dateStr, String pattern) {
		return LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(pattern));
	}

	public static LocalDateTime parseLocalDateTime(String dateTimeStr, String pattern) {
		return LocalDateTime.parse(dateTimeStr, DateTimeFormatter.ofPattern(pattern));
	}

	/**
	 * 日期相隔天数
	 *
	 * @param startDateInclusive
	 * @param endDateExclusive
	 * @return
	 */
	public static int periodDays(LocalDate startDateInclusive, LocalDate endDateExclusive) {
		return Period.between(startDateInclusive, endDateExclusive).getDays();
	}

	/**
	 * 日期相隔小时
	 *
	 * @param startInclusive
	 * @param endExclusive
	 * @return
	 */
	public static long durationHours(Temporal startInclusive, Temporal endExclusive) {
		return Duration.between(startInclusive, endExclusive).toHours();
	}

	/**
	 * 日期相隔分钟
	 *
	 * @param startInclusive
	 * @param endExclusive
	 * @return
	 */
	public static long durationMinutes(Temporal startInclusive, Temporal endExclusive) {
		return Duration.between(startInclusive, endExclusive).toMinutes();
	}

	/**
	 * 日期相隔毫秒数
	 *
	 * @param startInclusive
	 * @param endExclusive
	 * @return
	 */
	public static long durationMillis(Temporal startInclusive, Temporal endExclusive) {
		return Duration.between(startInclusive, endExclusive).toMillis();
	}

	/**
	 * 是否当天
	 *
	 * @param date
	 * @return
	 */
	public static boolean isToday(LocalDate date) {
		return getCurrentLocalDate().equals(date);
	}

	/**
	 * 获取本月的第一天
	 *
	 * @return
	 */
	public static String getFirstDayOfThisMonth() {
		return getCurrentLocalDate().with(TemporalAdjusters.firstDayOfMonth()).format(DATE_FORMATTER);
	}

	/**
	 * 获取本月的最后一天
	 *
	 * @return
	 */
	public static String getLastDayOfThisMonth() {
		return getCurrentLocalDate().with(TemporalAdjusters.lastDayOfMonth()).format(DATE_FORMATTER);
	}

	/**
	 * 获取2017-01的第一个周一
	 *
	 * @return
	 */
	public static String getFirstMonday() {
		return LocalDate.parse("2017-01-01").with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY))
				.format(DATE_FORMATTER);
	}

	/**
	 * 获取当前日期的后两周
	 *
	 * @return
	 */
	public static String getCurDateAfterTwoWeek() {
		return getCurrentLocalDate().plus(2, ChronoUnit.WEEKS).format(DATE_FORMATTER);
	}

	/**
	 * 获取当前日期的6个月后的日期
	 *
	 * @return
	 */
	public static String getCurDateAfterSixMonth() {
		return getCurrentLocalDate().plus(6, ChronoUnit.MONTHS).format(DATE_FORMATTER);
	}

	/**
	 * 获取当前日期的5年后的日期
	 *
	 * @return
	 */
	public static String getCurDateAfterFiveYear() {
		return getCurrentLocalDate().plus(5, ChronoUnit.YEARS).format(DATE_FORMATTER);
	}

	/**
	 * 获取当前日期的20年后的日期
	 *
	 * @return
	 */
	public static String getCurDateAfterTwentyYear() {
		return getCurrentLocalDate().plus(2, ChronoUnit.DECADES).format(DATE_FORMATTER);
	}

	/**
	 * 字符串转时间
	 *
	 * @return
	 */
	public static LocalDate stringToDate(String time) {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
		return LocalDate.parse(time, formatter);
	}

	public static Long getLongTime() {
		return new Date().getTime();
	}

}

总结

获取返回值时判断需处理多线程问题,如果线程数量固定切有序则无需处理,如果无序并且多次调用注意线程的并发。