use std::fs::{File, OpenOptions};
use std::io::{BufRead, BufReader, Seek, SeekFrom, Write};
use std::path::Path;
use std::thread;
use std::time::Duration;
use clap::{Command, arg};
fn main() {
let mut log_file_path_str: &str = "";
let mut index_file_path_str: &str = "";
let matches = Command::new("watch_log")
.version("1.0")
.author("357888473@qq.com")
.about("watch log and handle log every line")
.subcommand_required(true)
.arg_required_else_help(true)
.subcommand(
Command::new("logpath")
.about("log's path")
.arg(arg!(--logpath <VALUE>).help("String").required(true)),
)
.subcommand(
Command::new("indexpath")
.about("index's path")
.arg(arg!(--indexpath <VALUE>).help("save read log's line count").required(true)),
).get_matches();
match matches.subcommand() {
Some(("logpath", sub_matches)) => {
if let Some(input) = sub_matches.get_one::<String>("logpath") {
log_file_path_str = input;
}
},
Some(("indexpath", sub_matches)) => {
if let Some(input) = sub_matches.get_one::<String>("indexpath") {
index_file_path_str = input;
}
},
_ => unreachable!(),
}
let log_file_path = Path::new(log_file_path_str); // 日志文件路径
let index_file_path = Path::new(index_file_path_str); // 索引文件路径
loop {
let mut current_line_number = get_current_line_number(&index_file_path); // 获取上次读取的行数
let mut file = File::open(&log_file_path).unwrap(); // 打开日志文件
file.seek(SeekFrom::Start(0)).unwrap(); // 移动到文件开头
let reader = BufReader::new(&mut file);
let mut new_lines = false; // 用于标记是否有新的日志行读取
for line in reader.lines().skip(current_line_number as usize) {
let line = line.unwrap();
println!("{}", line);
current_line_number += 1; // 更新当前行数
new_lines = true;
}
if new_lines {
set_current_line_number(&index_file_path, current_line_number); // 更新索引文件中的行数
}
println!("等待新日志...");
thread::sleep(Duration::from_secs(1)); // 暂停1秒钟,然后重新开始循环
}
}
fn get_current_line_number(index_file_path: &Path) -> u64 {
if let Ok(index_content) = std::fs::read_to_string(index_file_path) {
// 读取索引文件中的内容,转换为已读行数
if let Ok(current_line_number) = index_content.trim().parse::<u64>() {
return current_line_number;
}
}
0 // 默认为0
}
fn set_current_line_number(index_file_path: &Path, line_number: u64) {
// 更新索引文件中的已读行数
let mut index_file = OpenOptions::new().write(true).create(true).truncate(true).open(index_file_path).unwrap();
writeln!(index_file, "{}", line_number).expect("无法写入索引文件");
}
请教给为,我用rust 通过命令行传入两个参数 logpath 和 indexpath,但是在执行的时候从事报错,我的执行命令是:
cargo run -- logpath=hello.log --indexpath=index.txt
报错是 error: unexpected argument '--logpath' found
我试过各种命令哈,再比如:
cargo run -- --logpath=hello.log --indexpath=index.txt
我查了很多资料,都无法解决,请各位大佬看下我上边代码,看看是否是我哪里有问题造成的,应该如何传参,谢谢
我猜你可能没有理解什么是子命令和选项参数
./abc xxx --dir="/tmp"
其中 xxx 是子命令(sub command),而 --dir 是选项参数(option)
所以如果是根据你的代码你应该运行的命令是
cargo run -- logpath --logpath="hello.log"
输出大概是:
因为你代码里面写了将 logpath 作为一个子命令,并且接收一个
--logpath
的选项。这挺奇怪的,所以我猜测你没理解。并且这样--indexpath
是没有办法同时输入的。我会认为你应该创建一个子命令
monitor
然后将--logpth
和--indexpath
作为选项才对。当然由于不知道你的具体需求,所以没法给出更多建议。我想你需要的是不是这样的实现: