java去調用並執行shell腳本學習記錄

java去調用並執行shell腳本


事件:由於幫同事看一個程序,裏面涉及到執行linux的命令,由於自己接觸的系統中並未遇到這樣的需求,所以修改完成後特此記錄!

廢話不多說,直接上具體實現代碼,如果在執行操作過程中遇到什麼問題,可先看看我上面的參考博客,還是無法解決可留言於我。

ShellJob類

package com.shelltest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.shelltest.util.ShellUtil;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;


/**
 * 執行sh腳本的job類
 * 可配置參數:
 * shDir, 腳本目錄,會自動執行下面所有腳本,可選
 * shPath, 腳本絕對路徑,只執行該腳本,可選
 *
 * @author zym
 * @date 2020/5/7 17:42
 */
public class ShellJob  {

    private static final Logger log = LoggerFactory.getLogger(ShellJob.class);

    /**
     * 腳本匹配後綴
     */
    private static final String SH_SUFFIX = ".sh";

    private String shPath;
    
    private String cron;

    public void setShPath(String shPath) {
        this.shPath = shPath;
    }

	public void setCron(String cron) {
		this.cron = cron;
	}

	@Override
	public String toString() {
		return "ShellJob [shDir=" + shDir + ", shPath=" + shPath + "]";
	}

    public void execute() {
		
        int path = shPath.lastIndexOf("/");
    	String newfile = shPath.substring(0,path)+File.separator + "cronfile.sh";
    	log.info("寫有crontab定時任務的腳本文件:{}", newfile);
    	File exesh = new File(newfile);
        try {
        	if(exesh.exists()){
        		exesh.delete();
        	}
        	exesh.createNewFile();
		} catch (IOException e) {
		     e.printStackTrace();
		} 
        
        cron = cron +" "+ shPath;
        log.info("crontab定時任務內容:{}", cron);

        writeInFile(exesh,cron);
        
        String execmd = "cat "+ exesh +" |crontab";
        boolean exeflag = execShell(execmd);
        if (exeflag){
        	log.info("執行crontab的定時任務:{}成功!", execmd);
        } else {
        	log.info("執行crontab的定時任務:{}失敗!", execmd);
        }
    /**
      * @describe 將crontab的內容寫入crontab的腳本文件
      * @author  fanny
      * @date 2020年5月13日 下午5:08:02
      * @version 1.0
      * @param  file 寫有定時任務執行腳本的文件
      * @param  content  定時任務時間
      * @return void
      * @throws Exception
      */
	 private  void writeInFile(File file, String content) {
	        Writer writer = null;
	        StringBuilder outputString = new StringBuilder();
	        try {
	            outputString.append(content + "\r\n");
	            writer = new FileWriter(file, true); // true表示追加
	            writer.write(outputString.toString());
	        } catch (IOException e) {
	            e.printStackTrace();
	        } finally {
	            try {
	                writer.close();
	            } catch (IOException e2) {
	                e2.printStackTrace();
	            }
	        }
	    }
   /**
     * 執行shell
     * @param shellPath shell路徑
     * @return 執行是否成功
     */
    public static boolean execShell(String shellPath) {
        int i = -1;
        if (StringUtil.isNotBlank(shellPath)) {
//            log.info("開始執行shell腳本:{}", shellPath);
            List<String> list = new ArrayList<>();
            list.add("/bin/sh");
            list.add("-c");
            list.add(shellPath);
            list.add(">/dev/null");
            list.add("2>&1");
            try {
                ProcessBuilder pb = new ProcessBuilder(list);
                Process p = pb.start();
                i = p.waitFor();
            } catch (InterruptedException | IOException e) {
                return false;
            }
        }

        return i == 0;
    }
     /**
     * 執行shell的main方法,需要將此工程(僅包含這一個類)打包爲可運行的jar後放到linux環境中執行
     * 
     * @return 執行是否成功
     */
    public static void main(String[] args) {
			 //定時任務執行時間,
		    String cron = "*/5 * * * * *";
		    //shell腳本路徑:
		    String shPath = "/home/fanny/shelltest/adf.sh"; 
		    log.info("cron:{},shPath:{}",cron,shPath);
			ShellJob evtJob = new ShellJob();
			evtJob.setShDir(shDir);
			evtJob.setShPath(shPath);
			evtJob.setCron(cron);
			evtJob.execute();
	}

   /**  另外再補充執行命令的另一種方法,我這裏是在執行例如:
     * chmod  755 filepath的賦權限的時候用到的,因爲我並不需要傳一個集合,
     * 採用那種方法可根據自己需求自行設計。
     * 執行本地命令
     * @param cmd 命令
     */
    public static boolean  execCmd(String cmd) {
    	boolean flag = false;
        Process process = null;
        try {
            process = Runtime.getRuntime().exec(cmd);
            process.waitFor();
            flag = true;
        } catch (Exception e) {
        	flag = false;
            log.error("命令執行異常: {}", cmd, e);
        } finally {
            if (process != null) {
                process.destroy();
            }
        }
        return flag;
    }
}

腳本adf.sh

#!/bin/bash
echo `"date '+%Y%m%d%H %H%M%S'`>>/home/fanny/shelltest/test.txt

說明

還有一種調用遠程主機來執行命令的操作,我這裏並未涉及,所以自己不曾去實踐,看了別的大神的博客:

以上兩篇博客也可供參考!

與君共勉!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章