rust从0开始写项目-06-如何接受命令行参数clap-01

写web项目或者app等,必不可少的要接受参数和校验参数的准确性,基本也是项目开始的第一步,那么我们今天来看下rust提供了哪些优秀的crates

关注 vx golang技术实验室,获取更多golang、rust好文

Part1一、clap_v3

本来是想用structOpt,但是看文档是这样描述的

由于 clap v3 现已发布,并且 structopt 功能已集成(几乎按原样),因此 structopt 现在处于维护模式:不会添加新功能。

错误将被修复,文档改进将被接受。

11. 1 添加依赖

[dependencies]
clap = { version = "4.2.7", features = ["derive","cargo"] }
features = "0.10.0"
cargo = "0.70.1"


或者
cargo add clap -- features  cargo
需要注意:如果不启用 cargo feature ,则会报如下错误。
requires `cargo` feature

如果使用command!arg! 必须在features 中添加cargo

21.2 快速启动

use std::env::Args;
/// clap_v3 原来的structOpt //
use std::path::PathBuf;

use clap::{arg, command, value_parser, ArgAction, Command};

fn test() {
    let matches = command!() // requires `cargo` feature
        .arg(arg!([name] "Optional name to operate on"))
        .arg(
            arg!(
                -c --config <FILE> "Sets a custom config file"
            )
                // We don't have syntax yet for optional options, so manually calling `required`
                .required(false)
                .value_parser(value_parser!(PathBuf)),
        )
        .arg(arg!(
            -d --debug ... "Turn debugging information on"
        ))
        .subcommand(
            Command::new("test")
                .about("does testing things")
                .arg(arg!(-l --list "lists test values").action(ArgAction::SetTrue)),
        )
        .get_matches();

    // You can check the value provided by positional arguments, or option arguments
    if let Some(name) = matches.get_one::<String>("name") {
        println!("Value for name: {name}");
    }

    if let Some(config_path) = matches.get_one::<PathBuf>("config") {
        println!("Value for config: {}", config_path.display());
    }

    // You can see how many times a particular flag or argument occurred
    // Note, only flags can have multiple occurrences
    match matches
        .get_one::<u8>("debug")
        .expect("Count'
s are defaulted")
    {
        0 => println!("
Debug mode is off"),
        1 => println!("
Debug mode is kind of on"),
        2 => println!("
Debug mode is on"),
        _ => println!("
Don't be crazy"),
    }

    // You can check for the existence of subcommands, and if found use their
    // matches just as you would the top level cmd
    if let Some(matches) = matches.subcommand_matches("test") {
        // "$ myapp test" was run
        if matches.get_flag("list") {
            // "$ myapp test -l" was run
            println!("Printing testing lists...");
        } else {
            println!("Not printing testing lists...");
        }
    }

    // Continued program logic goes here...
}

pub fn claps(){
    test()
}

1、默认执行情况

cargo run
Debug mode is off

2、参看帮助文档

cargo run --help
Run a binary or example of the local package

Usage: cargo run [OPTIONS] [args]...

Arguments:
  [args]...  Arguments for the binary or example to run

Options:
  -q, --quiet                   Do not print cargo log messages
      --bin [<NAME>]            Name of the bin target to run
      --example [<NAME>]        Name of the example target to run
  -p, --package [<SPEC>]        Package with the target to run
  -j, --jobs <N>                Number of parallel jobs, defaults to # of CPUs.
      --keep-going              Do not abort the build as soon as there is an error (unstable)
  -r, --release                 Build artifacts in release mode, with optimizations
      --profile <PROFILE-NAME>  Build artifacts with the specified profile
  -F, --features <FEATURES>     Space or comma separated list of features to activate
      --all-features            Activate all available features
      --no-default-features     Do not activate the `default` feature
      --target <TRIPLE>         Build for the target triple
      --target-dir <DIRECTORY>  Directory for all generated artifacts
      --manifest-path <PATH>    Path to Cargo.toml
      --message-format <FMT>    Error format
      --unit-graph              Output build graph in JSON (unstable)
      --ignore-rust-version     Ignore `rust-version` specification in packages
      --timings[=<FMTS>]        Timing output formats (unstable) (comma separated): html, json
  -h, --help                    Print help
  -v, --verbose...              Use verbose output (-vv very verbose/build.rs output)
      --color <WHEN>            Coloring: auto, always, never
      --frozen                  Require Cargo.lock and cache are up to date
      --locked                  Require Cargo.lock is up to date
      --offline                 Run without accessing the network
      --config <KEY=VALUE>      Override a configuration value
  -Z <FLAG>                     Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details

Run `cargo help run` for more detailed information.

3、使用 -dd 参数

cargo run -- -dd test 
Debug mode is on
Not printing testing lists...

31.3 command 解析器

1.3.1 基本使用

fn command(){
    let matches = Command::new("MyApp")
        .version("1.0")
        .author("ZHangQL Z <ZQL@gmail.com>")
        .about("this is the test project")
        .args(&[//次数是args,如果单个的的arg
            arg!(--config <FILE> "a required file for the configuration and no short").
                required(true)//必须包含
                .require_equals(true)//要求使用等号赋值
                // .default_value() //设置默认值
            ,
            arg!(-d --debug ... "turns on debugging information and allows multiples"),
            arg!([input] "an optional input file to use")
        ])
        .arg(arg!(--two <VALUE>).required(true))//单个的
        .get_matches();

    println!(
        "config: {:?}",
        matches.get_one::<String>("config").expect("required")
    );
    println!(
        "debug: {:?}",
        matches.get_one::<String>("debug")
    );
    println!(
        "input: {:?}",
        matches.get_one::<String>("input")
    );

}

查看help

RUST_BACKTRACE=1 cargo run  -- --help

this is the test project

Usage: my_test [OPTIONS] --config=<FILE> --two <VALUE> [input]

Arguments:
  [input]  an optional input file to use

Options:
      --config=<FILE>  a required file for the configuration and no short
  -d, --debug...       turns on debugging information and allows multiples
      --two <VALUE>    
  -h, --help           Print help
  -V, --version        Print version

运行

RUST_BACKTRACE=1 cargo run  -- --config=./config.yaml --two rrr lllll

config: "./config.yaml"
two: Some("rrr")
input: Some("lllll")

1.3.2 使用command!构建解析器

你也可以使用 command! 宏 构建解析器,不过要想使用 command! 宏,你需要开启 cargo feature。

use clap::{arg, command};

fn main() {
    // requires `cargo` feature, reading name, version, author, and description from `Cargo.toml`
    let matches = command!()
        .arg(arg!(--two <VALUE>).required(true))
        .arg(arg!(--one <VALUE>).required(true))
        .get_matches();

    println!(
        "two: {:?}",
        matches.get_one::<String>("two").expect("required")
    );
    println!(
        "one: {:?}",
        matches.get_one::<String>("one").expect("required")
    );
}

1.3.3 Command::next_line_help

使用 Command::next_line_help 方法 可以修改参数打印行为

use clap::{arg, command, ArgAction};

fn main() {
    let matches = command!() // requires `cargo` feature
        .next_line_help(true)
        .arg(arg!(--two <VALUE>).required(true).action(ArgAction::Set))
        .arg(arg!(--one <VALUE>).required(true).action(ArgAction::Set))
        .get_matches();

    println!(
        "two: {:?}",
        matches.get_one::<String>("two").expect("required")
    );
    println!(
        "one: {:?}",
        matches.get_one::<String>("one").expect("required")
    );
}

Usage: my_test [OPTIONS] --config=<FILE> --two <VALUE> [input]

Arguments:
  [input]
          an optional input file to use

Options:
      --config=<FILE>
          a required file for the configuration and no short
  -d, --debug...
          turns on debugging information and allows multiples
      --two <VALUE>
          
  -h, --help
          Print help
  -V, --version
          Print version

效果就是:参数的描述和参数是分行的,描述信息在参数下一行。

41.4 添加命令行参数(Adding Arguments)

我们可以使用 Command::arg 方法来添加 Arg 对象来添加命令行参数

fn adding_arg(){
    let matches = command!()
        .arg(Arg::new("name"))
        .get_matches();
    println!("name: {:?}", matches.get_one::<String>("name"));
}

查看help

RUST_BACKTRACE=1 cargo run  -- --help
Usage: my_test [name]

Arguments:
  [name]  

Options:
  -h, --help     Print help
  -V, --version  Print version

2、使用 name 参数:默认

cargo run
name: None

3、使用 name 参数:blob

注意定义的时候没有是直接使用的 不需要key的

cargo run bob
name: Some("bob")

1.4.2 设置参数行为

需要注意:参数默认值是一个 Set 类型

我们可以使用 Command::action 方法来设置 参数行为。如果可以添加多个只,我们可以使用 ArgAction::Append

use clap::{command, Arg, ArgAction};

fn main() {
    let matches = command!() // requires `cargo` feature
        .arg(Arg::new("name").action(ArgAction::Append))
        .get_matches();

    let args = matches
        .get_many::<String>("name")
        .unwrap_or_default()
        .map(|v| v.as_str())
        .collect::<Vec<_>>();

    println!("names: {:?}", &args);
}

51.5 参数选项

一个参数行为的标志:

  • 顺序无关
  • 可选参数
  • 意图清晰
fn arg_switch(){
    let matches = command!()
        .arg(Arg::new("name")
            .short('n')
            .long("name")
        ).get_matches();
    println!("name: {:?}", matches.get_one::<String>("name"));
}

上述代码:我们定义了一个name参数,缩写是n,全拼是name,也就是如下形式

-n, --name <name>

我们使用方式就有如下几种

cargo run -- --name blo
cargo run -- --name=blob
cargo run -- -n blob
cargo run -- -n=blob
cargo run -- -nblob

1.5.1 开启/关闭标志

我们可以是 ArgAction::SetTrue 开启参数

use clap::{command, Arg, ArgAction};

fn main() {
    let matches = command!() // requires `cargo` feature
        .arg(
            Arg::new("verbose")
                .short('v')
                .long("verbose")
                .action(ArgAction::SetTrue),
        )
        .get_matches();

    println!("verbose: {:?}", matches.get_flag("verbose"));

}

1.5.2参数调用计数

我们可以使用 ArgAction::Count

use clap::{command, Arg, ArgAction};

fn main() {
    let matches = command!() // requires `cargo` feature
        .arg(
            Arg::new("verbose")
                .short('v')
                .long("verbose")
                .action(ArgAction::Count),
        )
        .get_matches();

    println!("verbose: {:?}", matches.get_count("verbose"));
}

默认值是0,多次使用参数就会计数

cargo run --  --verbose --verbose

1.5.3 默认值

fn default_value(){
    let matches = command!() // requires `cargo` feature
        .arg(
            arg!([PORT])
                .value_parser(value_parser!(u16))
                .default_value("2023"),
        )
        .get_matches();

    println!(
        "port: {:?}",
        matches
            .get_one::<u16>("PORT")
            .expect("default ensures there is always a value")
    );

}
cargo run
port: 2023

cargo run 897
port: 897

1.5.4 参数校验

默认情况下,参数被认为是 String,并且使用 UTF-8 校验。

枚举值

fn enum_check(){
    let matches = command!() // requires `cargo` feature
        .arg(
            arg!(<MODE>)
                .help("What mode to run the program in")
                .value_parser(["fast""slow"]),
        )
        .get_matches();

    // Note, it's safe to call unwrap() because the arg is required
    match matches
        .get_one::<String>("MODE")
        .expect("'
MODE' is required and parsing will fail if its missing")
        .as_str()
    {
        "fast" => {
            println!("Hare");
        }
        "slow" => {
            println!("Tortoise");
        }
        _ => unreachable!(),
    }
}
cargo run rrr 
error: invalid value 'rrr' for '<MODE>'
  [possible values: fast, slow]

cargo run fast
Hare

如果我们开启了 derive feature, 则我们也可以实现 ValueEnum 特征实现相同的功能

use clap::{arg, builder::PossibleValue, command, value_parser, ValueEnum};

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
enum Mode {
    Fast,
    Slow,
}

// Can also be derived with feature flag `derive`
impl ValueEnum for Mode {
    fn value_variants<'a>() -> &'a [Self] {
        &[Mode::Fast, Mode::Slow]
    }

    fn to_possible_value<'a>(&self) -> Option<PossibleValue> {
        Some(match self {
            Mode::Fast => PossibleValue::new("fast").help("Run swiftly"),
            Mode::Slow => PossibleValue::new("slow").help("Crawl slowly but steadily"),
        })
    }

}

impl std::fmt::Display for Mode {
    fn fmt(&self, f: &mut std::fmt::Formatter<'
_>) -> std::fmt::Result {
        self.to_possible_value()
            .expect("no values are skipped")
            .get_name()
            .fmt(f)
    }
}

impl std::str::FromStr for Mode {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        for variant in Self::value_variants() {
            if variant.to_possible_value().unwrap().matches(s, false) {
                return Ok(*variant);
            }
        }
        Err(format!("invalid variant: {s}"))
    }

}

fn main() {
    let matches = command!() // requires `cargo` feature
        .arg(
            arg!(<MODE>)
                .help("What mode to run the program in")
                .value_parser(value_parser!(Mode)),
        )
        .get_matches();

    // Note, it's safe to call unwrap() because the arg is required
    match matches
        .get_one::<Mode>("MODE")
        .expect("'
MODE' is required and parsing will fail if its missing")
    {
        Mode::Fast => {
            println!("Hare");
        }
        Mode::Slow => {
            println!("Tortoise");
        }
    }

}

1.5.5 校验值

我们可以使用 Arg::value_parser 验证并解析成我们需要的任何类型。

fn validated(){
    let matches = command!() // requires `cargo` feature
        .arg(
            arg!(<PORT>)
                .help("Network port to use")
                .value_parser(value_parser!(u16).range(1..)),
        )
        .get_matches();

    // Note, it's safe to call unwrap() because the arg is required
    let port: u16 = *matches
        .get_one::<u16>("PORT")
        .expect("'
PORT' is required and parsing will fail if its missing");
    println!("PORT = {port}");

}

cargo run 0
error: invalid value '
0' for '<PORT>': 0 is not in 1..=65535

cargo run 1
PORT = 10

1.5.6 自定义解析器

我们也可以使用自定义解析器用于改进错误信息提示和额外的验证。

use std::ops::RangeInclusive;

use clap::{arg, command};

fn main() {
    let matches = command!() // requires `cargo` feature
        .arg(
            arg!(<PORT>)
                .help("Network port to use")
                .value_parser(port_in_range),
        )
        .get_matches();

    // Note, it's safe to call unwrap() because the arg is required
    let port: u16 = *matches
        .get_one::<u16>("PORT")
        .expect("'
PORT' is required and parsing will fail if its missing");
    println!("PORT = {port}");
}

const PORT_RANGE: RangeInclusive<usize> = 1..=65535;

fn port_in_range(s: &str) -> Result<u16, String> {
    let port: usize = s
        .parse()
        .map_err(|_| format!("`{s}` isn'
t a port number"))?;
    if PORT_RANGE.contains(&port) {
        Ok(port as u16)
    } else {
        Err(format!(
            "
port not in range {}-{}",
            PORT_RANGE.start(),
            PORT_RANGE.end()
        ))
    }
}

1.5。7 参数关系(Argument Relations)

我们可以声明 Arg 和 ArgGroup。ArgGroup 用于声明参数关系。

use std::path::PathBuf;

use clap::{arg, command, value_parser, ArgAction, ArgGroup};

fn main() {
    // Create application like normal
    let matches = command!() // requires `cargo` feature
        // Add the version arguments
        .arg(arg!(--"set-ver" <VER> "set version manually"))
        .arg(arg!(--major         "auto inc major").action(ArgAction::SetTrue))
        .arg(arg!(--minor         "auto inc minor").action(ArgAction::SetTrue))
        .arg(arg!(--patch         "auto inc patch").action(ArgAction::SetTrue))
        // Create a group, make it required, and add the above arguments
        .group(
            ArgGroup::new("vers")
                .required(true)
                .args(["set-ver""major""minor""patch"]),
        )
        // Arguments can also be added to a group individually, these two arguments
        // are part of the "input" group which is not required
        .arg(
            arg!([INPUT_FILE] "some regular input")
                .value_parser(value_parser!(PathBuf))
                .group("input"),
        )
        .arg(
            arg!(--"spec-in" <SPEC_IN> "some special input argument")
                .value_parser(value_parser!(PathBuf))
                .group("input"),
        )
        // Now let's assume we have a -c [config] argument which requires one of
        // (but **not** both) the "input" arguments
        .arg(
            arg!(config: -c <CONFIG>)
                .value_parser(value_parser!(PathBuf))
                .requires("input"),
        )
        .get_matches();

    // Let'
s assume the old version 1.2.3
    let mut major = 1;
    let mut minor = 2;
    let mut patch = 3;
    
    // See if --set-ver was used to set the version manually
    let version = if let Some(ver) = matches.get_one::<String>("set-ver") {
        ver.to_owned()
    } else {
        // Increment the one requested (in a real program, we'd reset the lower numbers)
        let (maj, min, pat) = (
            matches.get_flag("major"),
            matches.get_flag("minor"),
            matches.get_flag("patch"),
        );
        match (maj, min, pat) {
            (true, _, _) => major += 1,
            (_, true, _) => minor += 1,
            (_, _, true) => patch += 1,
            _ => unreachable!(),
        };
        format!("{major}.{minor}.{patch}")
    };
    
    println!("Version: {version}");
    
    // Check for usage of -c
    if matches.contains_id("config") {
        let input = matches
            .get_one::<PathBuf>("INPUT_FILE")
            .unwrap_or_else(|| matches.get_one::<PathBuf>("spec-in").unwrap())
            .display();
        println!(
            "Doing work using input {} and config {}",
            input,
            matches.get_one::<PathBuf>("config").unwrap().display()
        );
    }

}

此时 --set-ver |--major|--minor|--patch 是一个组的参数。

1.5.8 自定义校验(Custom Validation)

我们可以创建自定义校验错误 Command::error 方法可以返回指定错误 Error和自定义错误信息


use std::path::PathBuf;

use clap::error::ErrorKind;
use clap::{arg, command, value_parser, ArgAction};

fn main() {
    // Create application like normal
    let mut cmd = command!() // requires `cargo` feature
        // Add the version arguments
        .arg(arg!(--"set-ver" <VER> "set version manually"))
        .arg(arg!(--major         "auto inc major").action(ArgAction::SetTrue))
        .arg(arg!(--minor         "auto inc minor").action(ArgAction::SetTrue))
        .arg(arg!(--patch         "auto inc patch").action(ArgAction::SetTrue))
        // Arguments can also be added to a group individually, these two arguments
        // are part of the "input" group which is not required
        .arg(arg!([INPUT_FILE] "some regular input").value_parser(value_parser!(PathBuf)))
        .arg(
            arg!(--"spec-in" <SPEC_IN> "some special input argument")
                .value_parser(value_parser!(PathBuf)),
        )
        // Now let's assume we have a -c [config] argument which requires one of
        // (but **not** both) the "input" arguments
        .arg(arg!(config: -c <CONFIG>).value_parser(value_parser!(PathBuf)));
    let matches = cmd.get_matches_mut();

    // Let'
s assume the old version 1.2.3
    let mut major = 1;
    let mut minor = 2;
    let mut patch = 3;
    
    // See if --set-ver was used to set the version manually
    let version = if let Some(ver) = matches.get_one::<String>("set-ver") {
        if matches.get_flag("major") || matches.get_flag("minor") || matches.get_flag("patch") {
            cmd.error(
                ErrorKind::ArgumentConflict,
                "Can't do relative and absolute version change",
            )
            .exit();
        }
        ver.to_string()
    } else {
        // Increment the one requested (in a real program, we'd reset the lower numbers)
        let (maj, min, pat) = (
            matches.get_flag("major"),
            matches.get_flag("minor"),
            matches.get_flag("patch"),
        );
        match (maj, min, pat) {
            (true, false, false) => major += 1,
            (false, true, false) => minor += 1,
            (false, false, true) => patch += 1,
            _ => {
                cmd.error(
                    ErrorKind::ArgumentConflict,
                    "Can only modify one version field",
                )
                .exit();
            }
        };
        format!("{major}.{minor}.{patch}")
    };
    
    println!("Version: {version}");
    
    // Check for usage of -c
    if matches.contains_id("config") {
        let input = matches
            .get_one::<PathBuf>("INPUT_FILE")
            .or_else(|| matches.get_one::<PathBuf>("spec-in"))
            .unwrap_or_else(|| {
                cmd.error(
                    ErrorKind::MissingRequiredArgument,
                    "INPUT_FILE or --spec-in is required when using --config",
                )
                .exit()
            })
            .display();
        println!(
            "Doing work using input {} and config {}",
            input,
            matches.get_one::<PathBuf>("config").unwrap().display()
        );
    }

}

61.6、子命令(Subcommand)

我们可以使用 Command::subcommand 方法添加子命令。每一个子命令都自己的版本、作者、参数和它的子命令。

use clap::{arg, command, Command};

fn main() {
    let matches = command!() // requires `cargo` feature
        .propagate_version(true)
        .subcommand_required(true)
        .arg_required_else_help(true)
        .subcommand(
            Command::new("add")
                .about("Adds files to myapp")
                .arg(arg!([NAME])),
        )
        .get_matches();

    match matches.subcommand() {
        Some(("add", sub_matches)) => println!(
            "'myapp add' was used, name is: {:?}",
            sub_matches.get_one::<String>("NAME")
        ),
        _ => unreachable!("Exhausted list of subcommands and subcommand_required prevents `None`"),
    }

}


我们使用 Command::arg_required_else_help 如果参数不存在,优雅的退出。 使用 Command::propagate_version 可以打印命令的版本号

71.7、测试

我们可以使用 debug_assert! 宏 或者 使用 Command::debug_assert 方法。

use clap::{arg, command, value_parser};

fn main() {
    let matches = cmd().get_matches();

    // Note, it's safe to call unwrap() because the arg is required
    let port: usize = *matches
        .get_one::<usize>("PORT")
        .expect("'
PORT' is required and parsing will fail if its missing");
    println!("PORT = {port}");

}

fn cmd() -> clap::Command {
    command!() // requires `cargo` feature
        .arg(
            arg!(<PORT>)
                .help("Network port to use")
                .value_parser(value_parser!(usize)),
        )
}

#[test]
fn verify_cmd() {
    cmd().debug_assert();
}


本文由 mdnice 多平台发布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/203540.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Flink on k8s】- 3 - Kubernetes 中的关键概念

目录 1、容器 VS 虚拟机 2、Kubernetes 架构 2.1 Master节点 2.2 Node 节点 3、Kubernetes 的基本对象

华为OD机试 - 分披萨(Java JS Python C)

题目描述 "吃货"和"馋嘴"两人到披萨店点了一份铁盘(圆形)披萨,并嘱咐店员将披萨按放射状切成大小相同的偶数个小块。但是粗心的服务员将披萨切成了每块大小都完全不同奇数块,且肉眼能分辨出大小。 由于两人都想吃到最多的披萨,他们商量了一个他们认…

初识树型结构与二叉树

1. 树型结构 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树&#xff08;它是根朝上&#xff0c;而叶朝下的&#xff09;&#xff0c;其物理结构如下图所示&#x…

Ubuntu 20.04 安装 mysql8 LTS

Ubuntu 20.04 安装 mysql8 LTS sudo apt-get update sudo apt-get install mysql-server mysql --version mysql Ver 8.0.35-0ubuntu0.20.04.1 for Linux on x86_64 ((Ubuntu)) Ubuntu20.04 是自带了 MySQL8. 几版本的&#xff0c;低于 20.04 则默认安装是 MySQL5.7.33 s…

rpm安装gitlab

1.rpm包下载 https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/ 2.进行安装 rpm -ivh gitlab-ce-15.9.7-ce.0.el7.x86_64.rpm --nodeps --force 3.配置访问地址 vim /etc/gitlab/gitlab.rb 4.重新加载配置以及重启服务 gitlab-ctl reconfiguregitlab-ctl resta…

<Linux>(极简关键、省时省力)《Linux操作系统原理分析之Linux文件管理(2)》(26)

《Linux操作系统原理分析之Linux文件管理&#xff08;2&#xff09;》&#xff08;26&#xff09; 8 Linux文件管理8.4 虚拟文件系统 VFS8.4.1 VFS 的工作原理8.4.2 VFS 超级块8.4.3VFS 的 inode 8.5 文件系统的安装与注册8.5.2 文件系统的注册 8 Linux文件管理 8.4 虚拟文件系…

HarmonyOS4.0从零开始的开发教程05 应用程序入口—UIAbility的使用

HarmonyOS&#xff08;三&#xff09;应用程序入口—UIAbility的使用 UIAbility概述 UIAbility是一种包含用户界面的应用组件&#xff0c;主要用于和用户进行交互。UIAbility也是系统调度的单元&#xff0c;为应用提供窗口在其中绘制界面。 每一个UIAbility实例&#xff0c;…

python数据分析基础

前言 2023年10月以来&#xff0c;一位在商学院就读的可爱同学遇上了一门课——python数据分析&#xff0c;并遇到了许多问题&#xff0c;找上了我&#xff0c;就此&#xff0c;我也开始了学习之路&#xff0c;虽然很浅显&#xff0c;但这些东西对部门同学来说也是受用的&#…

【XILINX】ISE chipscope出现错误 Can‘t load jre bin client jvm.dll

记录一个ISE软件使用过程中遇到的问题及解决方案。 问题 ISE chipscope出现错误 Cant load jre bin client jvm.dll C:\Xilinx\14.7\ISE_DS\ISE\bin\nt C:\Xilinx\14.7\ISE_DS\.xinstall\bin\nt C:\Xilinx\14.7\ISE_DS\.xinstall\bin\nt64 C:\Xilinx\14.7\ISE_DS\ISE\bin\nt6…

Weblogic CVE-2023-21839(metasploit版)

Step1&#xff1a;用docker搭建环境 Step2&#xff1a;docker查看映射端口 Step3&#xff1a;访问特定端口&#xff0c;然后靶标应用。 Step4&#xff1a;用metasploit进行攻击&#xff1a; 首先&#xff0c;打开metasploit&#xff0c;然后查询需要攻击的板块&#xff0…

【恶意刷券】电商中恶意刷券如何防止?

好的&#xff0c;更详细一些的解释如下&#xff1a; 1. **验证码验证** 验证码验证是防范恶意刷券的最基本手段之一。通过在关键操作前引入验证码&#xff0c;可以让机器无法进行自动化操作&#xff0c;只有真实用户才能完成验证。验证码种类包括文字、图片、计算等多种形式&…

C# 未处理System.InvalidOperationException HResult=-2146233079

1.异常信息&#xff1a; 未处理System.InvalidOperationException HResult-2146233079 MessageThe custom trace listener custom listener does not have a listener type name set or the type is invalid (F:\CBCT64\Output\Polaris.exe.Config line 45). SourceMicr…

[实践总结] 使用Apache HttpClient 4.x进行进行一次Http请求

使用Apache HttpClient 4.x进行进行一次Http请求 依赖 <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient --> <dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactI…

相位解包裹算法的研究现状和存在的问题

位相解包裹算法的研究现状 Phase unwrapping中文译法有&#xff1a;位相展开&#xff0c;位相解包寝&#xff0c;位相解缠绕等。因为数字全总术的重要步骤就是进行位相解包裹&#xff0c;所以伴随着数字全息显微术的发展&#xff0c;就对位相解包裹算法提出了更高的要求&#x…

华为OD机试 - 机场航班调度程序(Java JS Python C)

题目描述 XX市机场停放了多架飞机,每架飞机都有自己的航班号CA3385,CZ6678,SC6508等,航班号的前2个大写字母(或数字)代表航空公司的缩写,后面4个数字代表航班信息。 但是XX市机场只有一条起飞跑道,调度人员需要安排目前停留在机场的航班有序起飞。 为保障航班的有序…

Python:核心知识点整理大全4-笔记

目录 2.6 Python 之禅 2.7 小结 3.1 列表是什么 3.1.1 访问列表元素 3.1.2 索引从 0 而不是 1 开始 3.1.3 使用列表中的各个值 3.2 修改、添加和删除元素 3.2.1 修改列表元素 3.2.2 在列表中添加元素 2. 在列表中插入元素 1. 使用del语句删除元素 1 处的代码使用del…

指定分隔符对字符串进行分割 numpy.char.split()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 指定分隔符对字符串进行分割 numpy.char.split() 选择题 请问下列程序运行的的结果是&#xff1a; import numpy as np print("【执行】np.char.split(I.Love.China, sep .)") p…

【Flink on k8s】- 11 - 使用 Flink kubernetes operator 运行 Flink 作业

目录 1、创建本地镜像库 1.1 拉取私人仓库镜像 1.2 运行 1.3 本地浏览器访问 5000 端口

Linux进程解析(冯诺依曼体系结构,操作系统,进程初步解析)

冯诺依曼体系结构&#xff1a; 我们常见的计算机&#xff0c;如笔记本。我们常见的计算机&#xff0c;服务器&#xff0c;大部分都遵守冯诺依曼体系。 截至目前&#xff0c;我们所认识的计算机&#xff0c;都是有一个个的硬件组件组成&#xff1a; 中央处理器(CPU)&am…

Linux socket编程(12):Unix套接字之socketpair、sendmsg和recvmsg详解

在上一篇文章Unix套接字编程及通信例子中&#xff0c;我们对Unix套接字编程有一个基本的了解。但在Unix套接字编程的领域中&#xff0c;有一组特殊而强大的工具&#xff1a;socketpair、sendmsg 和 recvmsg&#xff0c;它们为实现本地进程间通信提供了便捷的方式。 文章目录 1 …