事件:由於幫同事看一個程序,裏面涉及到執行linux的命令,由於自己接觸的系統中並未遇到這樣的需求,所以修改完成後特此記錄!
- 參考博客1:https://blog.csdn.net/vcfriend/article/details/81226632
- 參考博客2:https://blog.csdn.net/tterminator/article/details/82227394
廢話不多說,直接上具體實現代碼,如果在執行操作過程中遇到什麼問題,可先看看我上面的參考博客,還是無法解決可留言於我。
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
說明
還有一種調用遠程主機來執行命令的操作,我這裏並未涉及,所以自己不曾去實踐,看了別的大神的博客:
以上兩篇博客也可供參考!
與君共勉!!!