92 lines
2.3 KiB
Rust
92 lines
2.3 KiB
Rust
use std::{os::unix::process::CommandExt as _, process, thread, time};
|
|
|
|
use clap::Parser;
|
|
use env_logger::{Builder, DEFAULT_FILTER_ENV, DEFAULT_WRITE_STYLE_ENV};
|
|
use log::LevelFilter;
|
|
use rand::{thread_rng, Rng as _};
|
|
|
|
#[macro_use]
|
|
extern crate log;
|
|
|
|
#[derive(Parser, Debug)]
|
|
#[clap(version, about)]
|
|
struct Args {
|
|
/// Enable informational logs
|
|
#[clap(short, long)]
|
|
verbose: bool,
|
|
|
|
/// Enable debugging logs
|
|
#[clap(short, long)]
|
|
debug: bool,
|
|
|
|
/// Minimum number of seconds to sleep
|
|
#[clap(short, long, default_value_t = 1)]
|
|
min_seconds: u32,
|
|
|
|
/// Maximum number of seconds to sleep
|
|
max_seconds: u32,
|
|
|
|
/// Program followed by its arguments to execute
|
|
#[clap(takes_value = true, multiple_values = true, last = true)]
|
|
arguments: Vec<String>,
|
|
}
|
|
|
|
fn main() -> ! {
|
|
let args = Args::parse();
|
|
|
|
let mut builder = Builder::new();
|
|
builder.filter_level(if args.debug {
|
|
LevelFilter::Debug
|
|
} else if args.verbose {
|
|
LevelFilter::Info
|
|
} else {
|
|
LevelFilter::Warn
|
|
});
|
|
builder.parse_default_env();
|
|
builder.init();
|
|
|
|
if args.min_seconds > args.max_seconds {
|
|
error!(
|
|
"Wrong duration range [{}; {}]",
|
|
args.min_seconds, args.max_seconds
|
|
);
|
|
process::exit(2);
|
|
}
|
|
|
|
debug!(
|
|
"Now generating a random number between {} and {}...",
|
|
args.min_seconds, args.max_seconds
|
|
);
|
|
|
|
let n: u32 = thread_rng().gen_range(args.min_seconds..=args.max_seconds);
|
|
debug!("Random generator gave {}", n);
|
|
|
|
let duration = time::Duration::from_secs(n.into());
|
|
|
|
let now = time::Instant::now();
|
|
|
|
info!("Now sleeping {:?}...", duration);
|
|
thread::sleep(duration);
|
|
|
|
debug!("Actually slept {:?}", now.elapsed());
|
|
|
|
if args.arguments.is_empty() {
|
|
debug!("Nothing to execute, exiting!");
|
|
process::exit(0);
|
|
}
|
|
|
|
info!("Now executing {:?}...", args.arguments);
|
|
let error = process::Command::new(&args.arguments[0])
|
|
.args(&args.arguments[1..])
|
|
.env_remove(DEFAULT_FILTER_ENV)
|
|
.env_remove(DEFAULT_WRITE_STYLE_ENV)
|
|
.exec();
|
|
error!("Error while executing {:?}: {}", args.arguments, error);
|
|
|
|
process::exit(if let Some(raw_os_error) = error.raw_os_error() {
|
|
raw_os_error
|
|
} else {
|
|
1
|
|
});
|
|
}
|