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"
输出大概是:
cargo run -- logpath --logpath="/tmp/abc.log" Finished dev [unoptimized + debuginfo] target(s) in 0.04s Running `target/debug/let-code logpath --logpath=/tmp/abc.log`123
因为你代码里面写了将 logpath 作为一个子命令,并且接收一个 --logpath
的选项。这挺奇怪的,所以我猜测你没理解。并且这样 --indexpath
是没有办法同时输入的。
我会认为你应该创建一个子命令 monitor
然后将 --logpth
和 --indexpath
作为选项才对。当然由于不知道你的具体需求,所以没法给出更多建议。
我想你需要的是不是这样的实现:
use clap::{arg, Command};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("monitor").about("log's path").args([ arg!(--logpath <VALUE>).help("String").required(true), arg!(--indexpath <VALUE>).help("String").required(true), ])) .get_matches(); match matches.subcommand() { Some(("monitor", sub_matches)) => { if let Some(input) = sub_matches.get_one::<String>("logpath") { log_file_path_str = input; } if let Some(input) = sub_matches.get_one::<String>("indexpath") { index_file_path_str = input; } } _ => unreachable!(), } println!("{}, {}", log_file_path_str, index_file_path_str);}
$ cargo run -- monitor --logpath="/tmp/abc.log" --indexpath="/tmp/ttt.log"/tmp/abc.log, /tmp/ttt.log
你的代码看起来是正确的,但是在使用 cargo run
命令来运行 Rust 程序时,你需要知道 cargo run
命令实际上会先构建你的项目,然后运行构建出的可执行文件。因此,传递给程序的参数实际上需要传递给这个可执行文件,而不是 cargo run
命令。
在你的情况下,你可能需要两步来运行你的程序。首先,你需要构建你的项目:
cargo build
然后,你可以直接运行构建出的可执行文件,并传递参数给它。在你的例子中,可执行文件的名字可能是 watch_log
(这取决于你的 Cargo.toml
文件中 [package]
部分的 name
字段),因此你可以这样运行它:
./target/debug/watch_log logpath=hello.log indexpath=index.txt
或者,如果你正在使用 cargo 的默认配置(即,你的项目在 src/main.rs
文件中),那么构建出的可执行文件的名字应该是 target/debug/your_project_name
,其中 your_project_name
是你在 Cargo.toml
文件的 [package]
部分定义的 name
。所以,你可能需要这样运行它:
./target/debug/your_project_name logpath=hello.log indexpath=index.txt
注意,在这些命令中,我没有包含 --
在参数前面,因为 clap
库会自动处理这种情况。--logpath
和 --indexpath
是被 clap
定义为长选项的参数,所以你可以直接传递它们,而不需要 --
前缀。
希望这能解决你的问题!如果你还有其他问题,欢迎继续提问。
各位好,我用rust的axum进行学习,现在有个问题,我提供的代码 第一个函数传了2个参数,一个是info,一个是header,问题是:第一个info加上后没问题,但函数如果加上第二个参数 下边一行.route中的api::post_foo就会报错,如果我把两个参数任意一个参数去掉,都不会报错。所以我就不知道该怎么办了,我其实是想拿到post的json数据,以及查看header,甚至想看reque
Rust教程没有解释如何从命令行获取参数。在所有示例中,< code>fn main()只显示了一个空参数列表。 从 访问命令行参数的正确方法是什么?
问题内容: 我正在A中使用RUN指令安装rpm 但是,我想将值“ 2.3”作为参数传递。我的RUN指令应类似于: 哪里 问题答案: 您正在寻找和指导。这些是Docker 1.9中的新功能。查看https://docs.docker.com/engine/reference/builder/#arg。这将允许您添加到,然后使用构建。
问题内容: 我是JavaScript和jQuery的新手。我想显示一个combobox-A,它是一个HTML ,其选择的内容位于onChange()的另一位置。 如何传递带有其select的完整组合框,以及如何在onChange事件触发时传递其他参数? 问题答案: function getComboA(selectObject) { 上面的示例为您提供OnChange事件上组合框的选定值。
问题内容: 将参数传递给已编译的代码: 结果是: 显示已通过的用户名。 目的: 为了防止每次测试代码时都需要手动构建和运行代码,目的是编写一个能够测试参数传递的测试。 尝试 运行以下测试: 结果是: 问题 它看起来像那样不能够这个参数传递给函数的结果是不是 问题答案: 根据我的评论,第一个值是可执行文件本身的(路径),因此应解决您的问题。您可以从标准包中查看标志测试,他们正在做类似的事情。 另外,
本文向大家介绍如何获取路由传过来的参数?相关面试题,主要包含被问及如何获取路由传过来的参数?时的应答技巧和注意事项,需要的朋友参考一下 如果使用方式传入的参数使用 接收 如果使用方式传入的参数使用接收 参考:路由组件传参