-설명 추가예정
use clap::Parser;
use std::process::Command;
use std::thread;
use std::time::{Duration, SystemTime};
use std::fs;
use std::os::unix::fs::PermissionsExt;
use std::path::Path;
/// Simple heartbeat command-line app
#[derive(Parser)]
#[clap(author, version, about, long_about = None)]
struct Args {
/// Interval in seconds between checks
#[clap(short, long, value_parser)]
interval: u64,
/// Shell script to execute
#[clap(short = 's', long, value_parser)]
script: Option<String>,
/// The command to execute
#[clap(value_parser, trailing_var_arg = true)]
command: Vec<String>,
}
fn main() {
let args = Args::parse();
let interval = args.interval;
loop {
let start = SystemTime::now();
let output = if let Some(script_path) = &args.script {
// Check if the script is executable
if !is_executable(script_path) {
eprintln!("Error: The script '{}' is not executable.", script_path);
return;
}
// Execute the script directly
println!("in {}", script_path);
Command::new(script_path)
.output()
.expect("Failed to execute script")
} else {
// Execute the command
Command::new("sh")
.arg("-c")
.arg(args.command.join(" "))
.output()
.expect("Failed to execute command")
};
let status = match output.status.code() {
Some(0) => String::from("OK"),
Some(code) => format!("Failed: Exit Code {}", code),
None => String::from("Failed: Unknown Error"),
};
println!(
"{}: {}",
start.duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs(),
status
);
thread::sleep(Duration::from_secs(interval));
}
}
fn is_executable<P: AsRef<Path>>(path: P) -> bool {
fs::metadata(path)
.map(|metadata| metadata.permissions().mode() & 0o111 != 0)
.unwrap_or(false)
}
cargo run -- -i 30 "curl -sf localhost/health_check"