ventana utilizar sistema operativo lineas linea introduccion cual como comandos comando command-line rust

command-line - utilizar - linea de comandos del sistema operativo



¿Cómo acceder a los parámetros de línea de comando? (11)

A partir de la versión 0.8 / 0.9, la ruta correcta a la función args () sería ::std::os::args , es decir:

fn main() { let args: ~[~str] = ::std::os::args(); println(args[0]); }

Parece que Rust sigue siendo bastante volátil ahora con IO estándar, por lo que puede quedar obsoleto con bastante rapidez.

El tutorial de Rust no explica cómo tomar parámetros de la línea de comando. fn main() solo se muestra con una lista de parámetros vacía en todos los ejemplos.

¿Cuál es la forma correcta de acceder a los parámetros de línea de comandos desde main ?


El capítulo "No stdlib" del libro de Rust cubre cómo acceder a los parámetros de las líneas de comando (de otra manera).

// Entry point for this program #[start] fn start(_argc: isize, _argv: *const *const u8) -> isize { 0 }

Ahora, el ejemplo también tiene #![no_std] lo que creo que significa que normalmente, la biblioteca std tendría el verdadero punto de entrada para su binario y llamaría a una función global llamada main() . Otra opción es ''desactivar el shim main '' con #![no_main] . Lo cual, si no me equivoco, es decirle al compilador que usted tiene el control total sobre cómo se inicia su programa.

#![no_std] #![no_main] #[no_mangle] // ensure that this symbol is called `main` in the output pub extern fn main(argc: isize, argv: *const *const u8) -> isize { 0 }

No creo que esta sea una ''buena'' manera de hacer las cosas si lo único que quieres hacer es leer los argumentos de la línea de comando. El módulo std::os mencionado en otras respuestas parece ser una forma mucho mejor de hacer las cosas. Publico esta respuesta para completarla.


El análisis de argumentos cli de estilo getopt tiene lugar en el módulo getopts .


Para mí, getopts siempre se sintió demasiado bajo y docopt.rs era demasiado mágico. Quiero algo explícito y directo que todavía proporcione todas las características si las necesito.

Aquí es donde clap-rs es útil.
Se siente un poco como argparse de Python. Aquí hay un ejemplo de cómo se ve:

let matches = App::new("myapp") .version("1.0") .author("Kevin K. <[email protected]>") .about("Does awesome things") .arg(Arg::with_name("CONFIG") .short("c") .long("config") .help("Sets a custom config file") .takes_value(true)) .arg(Arg::with_name("INPUT") .help("Sets the input file to use") .required(true) .index(1)) .arg(Arg::with_name("debug") .short("d") .multiple(true) .help("Sets the level of debugging information")) .get_matches();

Puede acceder a sus parámetros de esta manera:

println!("Using input file: {}", matches.value_of("INPUT").unwrap()); // Gets a value for config if supplied by user, or defaults to "default.conf" let config = matches.value_of("CONFIG").unwrap_or("default.conf"); println!("Value for config: {}", config);

(Copiado de la documentación oficial )


Puede acceder a los argumentos de línea de comando utilizando las funciones std::env::args o std::env::args_os . Ambas funciones devuelven un iterador sobre los argumentos. El primero itera sobre String s (que es fácil de usar) pero entra en pánico si uno de los argumentos no es válido como unicode. Este último itera sobre OsString y nunca entra en pánico.

Tenga en cuenta que el primer elemento del iterador es el nombre del programa en sí (esto es una convención en todos los sistemas operativos principales), por lo que el primer argumento es en realidad el segundo elemento iterado.

Una manera fácil de lidiar con el resultado de args es convertirlo en un Vec :

use std::env; fn main() { let args: Vec<_> = env::args().collect(); if args.len() > 1 { println!("The first argument is {}", args[1]); } }

Puede usar la caja de herramientas del iterador estándar completo para trabajar con estos argumentos. Por ejemplo, para recuperar solo el primer argumento:

use std::env; fn main() { if let Some(arg1) = env::args().nth(1) { println!("The first argument is {}", arg1); } }

Puede encontrar bibliotecas en crates.io para analizar argumentos de líneas de comando:

  • docopt : solo escribe el mensaje de ayuda y el código de análisis se genera para ti.
  • clap : describe las opciones que desea analizar con una API fluida. Más rápido que docopt y te da más control.
  • getopts : puerto de la popular biblioteca C. Nivel inferior y aún más control.
  • structopt : construido sobre la structopt , es aún más ergonómico de usar.

Rust cambió de nuevo. os::args() está en desuso en favor de std::args() . Pero std::args() no es una matriz, devuelve un iterador . Puede iterar sobre los argumentos de línea de comando, pero no puede acceder a ellos con subíndices.

http://doc.rust-lang.org/std/env/fn.args.html

Si desea los argumentos de la línea de comando como un vector de cadenas, esto funcionará ahora:

use std::env; ... let args: Vec<String> = env::args().map(|s| s.into_string().unwrap()).collect();

Rust: aprende a abrazar el dolor del cambio.


Rust ha evolucionado desde la respuesta de Calvin desde mayo de 2013. Ahora uno analizaría los argumentos de línea de comando con as_slice() :

use std::os; fn seen_arg(x: uint) { println!("you passed me {}", x); } fn main() { let args = os::args(); let args = args.as_slice(); let nitems = { if args.len() == 2 { from_str::<uint>(args[1].as_slice()).unwrap() } else { 10000 } }; seen_arg(nitems); }


También echa un vistazo a structopt:

extern crate structopt; #[macro_use] extern crate structopt_derive; use structopt::StructOpt; #[derive(StructOpt, Debug)] #[structopt(name = "example", about = "An example of StructOpt usage.")] struct Opt { /// A flag, true if used in the command line. #[structopt(short = "d", long = "debug", help = "Activate debug mode")] debug: bool, /// An argument of type float, with a default value. #[structopt(short = "s", long = "speed", help = "Set speed", default_value = "42")] speed: f64, /// Needed parameter, the first on the command line. #[structopt(help = "Input file")] input: String, /// An optional parameter, will be `None` if not present on the /// command line. #[structopt(help = "Output file, stdout if not present")] output: Option<String>, } fn main() { let opt = Opt::from_args(); println!("{:?}", opt); }

https://github.com/TeXitoi/structopt


lo que @barjak dijo que funciona para cadenas, pero si necesitas el argumento como un número (en este caso un uint) necesitas convertirlo así:

fn main() { let arg : ~[~str] = os::args(); match uint::from_str(arg[1]){ Some(x)=>io::println(fmt!("%u",someFunction(x))), None=>io::println("I need a real number") } }


Docopt también está disponible para Rust, que genera un analizador para ti a partir de una cadena de uso. Como una ventaja en Rust, se puede usar una macro para generar automáticamente la estructura y hacer una decodificación basada en el tipo:

docopt!(Args, " Usage: cp [-a] SOURCE DEST cp [-a] SOURCE... DIR Options: -a, --archive Copy everything. ")

Y puedes obtener los argumentos con:

let args: Args = Args::docopt().decode().unwrap_or_else(|e| e.exit());

El LÉAME y la documentation tienen muchos ejemplos completos de trabajo.

Descargo de responsabilidad: soy uno de los autores de esta biblioteca.


A partir de versiones más nuevas de Rust (Rust> 0.10 / 11), la sintaxis de matriz no funcionará. Tendrás que usar el método get.

[Editar] La sintaxis de matriz funciona (nuevamente) en las noches. Entonces puede elegir entre el índice getter o array.

use std::os; fn main() { let args = os::args(); println!("{}", args.get(1)); } // Compile rustc args.rs && ./args hello-world // returns hello-world