use std::env;
use std::process;
fn main() {
let args: Vec<_> = env::args().collect();
println!("{} Parameters...", args.len());
for i in 0..args.len() {
println!("Parameter {} : {}", i, args[i]);
}
if args.len() != 2 {
println!("Just one parameter please");
process::exit (1);
}
println!("Hello {}", args[1]);
}Rust también ofrece los parámetros en un array incluyendo el nombre del programa como primero de esos parámetros. La forma de obtener este array no es tan inmediata como en otros lenguajes y require el uso de un par de paquetes estándar.
En Rust no es posible cambiar el nombre del proceso sobrescribiendo
la primera entrada de env::args de una forma estándar. Como
sucede con otros lenguajes, lo que si es posible es utilizar
prctl.
AL igual que con el resto de lenguajes que hemos visto,
rust ofrece varios paquetes para poder procesar la línea de
comandos de forma fácil y sencilla.
Debo decir que he intentado usar el paquete
getoptsque emula el paquete estándar UNIX, y el paqueteclapsque parece ser la elección más común. Con ambos me enfrentado a un infierno de dependencias y versiones puesto que mi contenedor ejecutaba una versión vieja de Rust. Imagino que esto es debido a mi poca experiencia concargo, pero debo decir que con el resto de los lenguajes en este libro, he tenido cero problemas.
El paquete que vamos a usar para tener más flexibilidad a la hora de
procesar la línea de comandos es pico_args. Puesto que en
esta ocasión necesitamos utilizar un paquete externo, utilizaremos la
utilidad cargo para manejar nuestro proyecto.
Primero crearemos un proyecto e incluiremos la dependencia que necesitamos.
$ cargo new cmdline-rust $ cd cmdline-rust $ echo "pico = \"0.5\"" >> Cargo.toml
Ahora podemos incluir nuestro código en el fichero
src/main. Algo como esto:
use pico_args::Arguments;
fn main() {
let mut args = Arguments::from_env();
if args.contains(["-h", "--help"]) {
println!("Usage:");
println!(" app [-h] [-i FILE] [-o FILE]");
println!();
println!("Options:");
println!(" -h, --help Show this help");
println!(" -i, --input FILE Input file");
println!(" -o, --output FILE Output file");
return;
}
let input: String =
args.opt_value_from_str(["-i", "--input"])
.unwrap().unwrap_or_else(|| "input.txt".to_string());
let output: String =
args.opt_value_from_str(["-o", "--output"])
.unwrap().unwrap_or_else(|| "output.txt".to_string());
println!("input: {:?}", input);
println!("output: {:?}", output);
}Como podemos ver, la primera línea Arguments::from_env()
es la encargada de hacer la parsing de los argumentos y nos
ofrece diferentes funciones para acceder a esta información. En concreto
en este ejemplo:
args.containsnos permite comprobar si alguno de los argumentos se corresponde con el flag que indicamos.args.opt_value_from_strinterpreta un par clave valor opcional, pero si la clave se encuentra, el valor también debe estar, de lo contrario se devuelve un error.
Otras funciones que os pueden resultar interesantes son:
args.value_from_str, funciona igual queopt_value_from_strpero en este caso se produce un error si el par clave-valor no se encuentra, o en otras palabras, utilizamos esta función para procesar argumentos obligatorios.args.finish()que retorna la lista de argumentos extra, es decir, todos los que todavía no se han procesado.
Como podéis ver pico_args nos permite indicar varias
claves para el mismo parámetro, lo que hace muy sencillo utilizar
argumentos cortos y largos.
RESUMEN
- Rust nos permite acceder a los argumentos de la línea de comandos
como un array de cadenas de caracteres usando
env::args() - El nombre del ejecutable se recibe en el primer parámetro, pero
modificarlo (lo cual no es trivial) no tienen ningún efecto en la salida
de utilidades como
ps. - Rust ofrece varios paquete para procesar los argumentos de la línea de comandos de forma fácil y sencilla.
■
