diff --git a/src/main/java/com/tongran/agent/client/service/impl/AgentServiceImpl.java b/src/main/java/com/tongran/agent/client/service/impl/AgentServiceImpl.java index f789eca..1ddf808 100644 --- a/src/main/java/com/tongran/agent/client/service/impl/AgentServiceImpl.java +++ b/src/main/java/com/tongran/agent/client/service/impl/AgentServiceImpl.java @@ -832,24 +832,63 @@ public class AgentServiceImpl implements AgentService { @Override public void checkTrAgent() { - // 脚本路径(用于验证脚本是否存在) - String SCRIPT_PATH = properties.getScriptPath()+"/check-tragent.sh"; + String CRON_FILE_PATH = properties.getScriptPath()+"/tr_live.cron"; + String NEW_CRON_ENTRY = "*/10 * * * * "+properties.getScriptPath()+"/check-tragent.sh >/dev/null 2>&1"; + String TARGET_SCRIPT = properties.getScriptPath()+"/check-tragent.sh"; try { - AgentDataUtil.chmod(SCRIPT_PATH,"775"); - } catch (IOException e) { - e.printStackTrace(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - // 要添加的定时任务(每10分钟执行一次,且静默输出) - String TARGET_CRON = "*/10 * * * * "+properties.getScriptPath()+"/check-tragent.sh >/dev/null 2>&1"; + // 验证当前定时任务中是否已包含目标脚本 + if (CrontabManager.isCronEntryExists(TARGET_SCRIPT)) { + AssertLog.info("当前定时任务中已包含 {}",TARGET_SCRIPT); + AssertLog.info("无需重复添加定时任务"); + return; // 如果已存在,直接退出 + } + AssertLog.info("当前定时任务中未找到 {}",TARGET_SCRIPT); + AssertLog.info("开始执行定时任务管理流程..."); - boolean success = CrontabManager.ensureCronJobExists(TARGET_CRON, SCRIPT_PATH); - if (success) { - System.out.println("✅ Crontab 状态正常。"); - } else { - System.err.println("❌ 操作失败,请检查权限或路径。"); + // 0. 清空 tr_live.cron 文件内容 + CrontabManager.clearCronFile(properties.getScriptPath(), CRON_FILE_PATH); + + // 1. 备份当前定时任务到文件 + CrontabManager.backupCurrentCrontab(CRON_FILE_PATH); + + // 2. 在文件末尾添加新的定时任务 + CrontabManager.appendNewCronEntry(CRON_FILE_PATH, NEW_CRON_ENTRY); + + // 3. 清除当前所有定时任务 + CrontabManager.clearCurrentCrontab(); + + // 4. 重新加载定时任务文件 + CrontabManager.installNewCrontab(CRON_FILE_PATH); + + AssertLog.info("定时任务管理完成!"); + + // 验证最终结果 + CrontabManager.verifyFinalResult(TARGET_SCRIPT); + + } catch (Exception e) { + AssertLog.info("执行定时任务管理时发生错误: " + e.getMessage()); + e.printStackTrace(); } + +//----------------------------------- +// // 脚本路径(用于验证脚本是否存在) +// String SCRIPT_PATH = properties.getScriptPath()+"/check-tragent.sh"; +// try { +// AgentDataUtil.chmod(SCRIPT_PATH,"775"); +// } catch (IOException e) { +// e.printStackTrace(); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } +// // 要添加的定时任务(每10分钟执行一次,且静默输出) +// String TARGET_CRON = "*/10 * * * * "+properties.getScriptPath()+"/check-tragent.sh >/dev/null 2>&1"; +// +// boolean success = CrontabManager.ensureCronJobExists(TARGET_CRON, SCRIPT_PATH); +// if (success) { +// System.out.println("✅ Crontab 状态正常。"); +// } else { +// System.err.println("❌ 操作失败,请检查权限或路径。"); +// } } @Override diff --git a/src/main/java/com/tongran/agent/client/utils/CrontabManager.java b/src/main/java/com/tongran/agent/client/utils/CrontabManager.java index 0d029ae..7b1311d 100644 --- a/src/main/java/com/tongran/agent/client/utils/CrontabManager.java +++ b/src/main/java/com/tongran/agent/client/utils/CrontabManager.java @@ -1,6 +1,9 @@ package com.tongran.agent.client.utils; import java.io.*; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; import java.util.concurrent.TimeUnit; public class CrontabManager { @@ -63,6 +66,7 @@ public class CrontabManager { newCrontab += CRON_JOB + "\n"; } + // 4. 写入新的 crontab ProcessBuilder pbWrite = new ProcessBuilder("crontab", "-"); pbWrite.redirectErrorStream(true); @@ -106,4 +110,217 @@ public class CrontabManager { // System.err.println("❌ 操作失败,请检查权限或路径。"); // } } + + /** + * 验证当前定时任务中是否包含目标脚本 + */ + public static boolean isCronEntryExists(String TARGET_SCRIPT) { + try { + AssertLog.info("验证: 检查当前定时任务是否包含 {}",TARGET_SCRIPT); + + Process process = Runtime.getRuntime().exec("crontab -l"); + BufferedReader reader = new BufferedReader( + new InputStreamReader(process.getInputStream()) + ); + String line; + while ((line = reader.readLine()) != null) { + if (line.contains(TARGET_SCRIPT)) { + AssertLog.info("✅ 发现目标脚本在当前定时任务中: {}",line.trim()); + reader.close(); + return true; + } + } + reader.close(); + int exitCode = process.waitFor(); + if (exitCode != 0 && exitCode != 1) { // exitCode 1 表示没有 crontab + throw new IOException("获取当前 crontab 失败,退出码: " + exitCode); + } + AssertLog.info("当前定时任务中未找到目标脚本"); + return false; + }catch (IOException | InterruptedException e) { + System.err.println("操作 crontab 失败:" + e.getMessage()); + e.printStackTrace(); + return false; + } + } + /** + * 0. 清空 tr_live.cron 文件内容 + */ + public static void clearCronFile(String cronDir, String CRON_FILE_PATH) { + try { + AssertLog.info("步骤0: 清空 {} 文件内容",CRON_FILE_PATH); + + // 确保目录存在 + new File(cronDir).mkdirs(); + + // 创建空文件(如果不存在)或清空现有内容 + Files.write(Paths.get(CRON_FILE_PATH), new byte[0]); + + AssertLog.info("✅ {} 文件已清空",CRON_FILE_PATH); + }catch (IOException e) { + System.err.println("操作 crontab 失败:" + e.getMessage()); + e.printStackTrace(); + } + + } + /** + * 1. 备份当前定时任务到文件 + */ + public static void backupCurrentCrontab(String CRON_FILE_PATH) { + try { + AssertLog.info("步骤1: 备份当前定时任务到 {}",CRON_FILE_PATH); + Process process = Runtime.getRuntime().exec("crontab -l"); + BufferedReader reader = new BufferedReader( + new InputStreamReader(process.getInputStream()) + ); + // 读取当前 crontab 内容 + StringBuilder currentCrontab = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + currentCrontab.append(line).append("\n"); + } + reader.close(); + int exitCode = process.waitFor(); + if (exitCode != 0 && exitCode != 1) { // exitCode 1 表示没有 crontab + throw new IOException("获取当前 crontab 失败,退出码: " + exitCode); + } + + // 写入当前定时任务内容 + Files.write(Paths.get(CRON_FILE_PATH), currentCrontab.toString().getBytes()); + + AssertLog.info("✅ 当前定时任务已保存到: {}",CRON_FILE_PATH); + }catch (IOException | InterruptedException e) { + System.err.println("操作 crontab 失败:" + e.getMessage()); + e.printStackTrace(); + } + + } + + /** + * 2. 在文件末尾添加新的定时任务 + */ + public static void appendNewCronEntry(String CRON_FILE_PATH, String NEW_CRON_ENTRY) { + try { + AssertLog.info("步骤2: 在文件末尾添加新定时任务"); + + // 检查是否已存在该定时任务 + String fileContent = new String(Files.readAllBytes(Paths.get(CRON_FILE_PATH))); + if (fileContent.contains(NEW_CRON_ENTRY)) { + AssertLog.info("⚠️ 定时任务已存在,跳过添加"); + return; + } + + // 添加新定时任务到文件末尾 + Files.write( + Paths.get(CRON_FILE_PATH), + (NEW_CRON_ENTRY + "\n").getBytes(), + StandardOpenOption.APPEND + ); + AssertLog.info("✅ 新定时任务已添加到文件末尾"); + }catch (IOException e) { + System.err.println("操作 crontab 失败:" + e.getMessage()); + e.printStackTrace(); + } + + } + + /** + * 3. 清除当前所有定时任务 + */ + public static void clearCurrentCrontab() { + try { + AssertLog.info("步骤3: 清除当前所有定时任务"); + + // 创建一个空的临时文件 + File tempFile = File.createTempFile("empty_cron", ".tmp"); + tempFile.deleteOnExit(); + + // 用空文件替换当前 crontab + Process process = Runtime.getRuntime().exec("crontab " + tempFile.getAbsolutePath()); + int exitCode = process.waitFor(); + + if (exitCode != 0) { + throw new IOException("清除当前 crontab 失败,退出码: " + exitCode); + } + + AssertLog.info("✅ 当前所有定时任务已清除"); + }catch (IOException | InterruptedException e) { + System.err.println("操作 crontab 失败:" + e.getMessage()); + e.printStackTrace(); + } + } + + /** + * 4. 重新加载定时任务文件 + */ + public static void installNewCrontab(String CRON_FILE_PATH) { + try { + AssertLog.info("步骤4: 加载新的定时任务文件"); + + // 检查文件是否存在 + if (!Files.exists(Paths.get(CRON_FILE_PATH))) { + throw new IOException("定时任务文件不存在: " + CRON_FILE_PATH); + } + + // 执行 crontab 命令加载新文件 + Process process = Runtime.getRuntime().exec("crontab " + CRON_FILE_PATH); + + // 读取输出 + BufferedReader stdout = new BufferedReader( + new InputStreamReader(process.getInputStream()) + ); + BufferedReader stderr = new BufferedReader( + new InputStreamReader(process.getErrorStream()) + ); + + String outputLine; + while ((outputLine = stdout.readLine()) != null) { + System.out.println("STDOUT: " + outputLine); + } + String errorLine; + while ((errorLine = stderr.readLine()) != null) { + System.err.println("STDERR: " + errorLine); + } + + int exitCode = process.waitFor(); + if (exitCode != 0) { + throw new IOException("加载新 crontab 失败,退出码: " + exitCode); + } + + AssertLog.info("✅ 新定时任务已成功加载"); + }catch (IOException | InterruptedException e) { + System.err.println("操作 crontab 失败:" + e.getMessage()); + e.printStackTrace(); + } + } + /** + * 验证最终结果 + */ + public static void verifyFinalResult(String TARGET_SCRIPT) { + try { + AssertLog.info("\n--- 验证最终定时任务结果 ---"); + Process process = Runtime.getRuntime().exec("crontab -l"); + BufferedReader reader = new BufferedReader( + new InputStreamReader(process.getInputStream()) + ); + + boolean found = false; + String line; + while ((line = reader.readLine()) != null) { + System.out.println(line); + if (line.contains(TARGET_SCRIPT)) { + AssertLog.info("✅ 确认 " + TARGET_SCRIPT + " 已成功添加到定时任务中"); + found = true; + } + } + reader.close(); + + if (!found) { + AssertLog.info("❌ 未在当前定时任务中找到目标脚本"); + } + + } catch (Exception e) { + AssertLog.info("验证 crontab 时出错: " + e.getMessage()); + } + } } \ No newline at end of file