Warning: Undefined array key "HTTP_ACCEPT_LANGUAGE" in /srv/vhost/diaridigital.net/home/html/sourcecode/includes/config.php on line 61

Deprecated: substr(): Passing null to parameter #1 ($string) of type string is deprecated in /srv/vhost/diaridigital.net/home/html/sourcecode/includes/config.php on line 61
Línea de comandos con flags
Source Code

Línea de comandos con flags


Tiempo de lectura: 2 minutos

Si necesitamos procesar una línea de comandos que incluye indicadores (flags), el paquete Flags permite analizar gramaticalmente de forma fácil todos los argumentos.



Las opciones o flags

Los flags son una manera de especificar opciones desde la línea de comando. Go ya proporciona un paquete integrado, flag, que simplifica el proceso de análisis sintáctico de indicadores (flags) de la línea de comandos.

Cómo se define un flag

Podemos definir un indicador como un tipo string, int o bool.

Por ejemplo, este código define un entero flag.Int(), almacenado en un puntero intFlag, del tipo int y con el valor por defecto 123 y un texto para la ayuda.

import "flag"

var intFlag = flag.Int("int", 123, "mensaje de la ayuda para este argumento")

De la misma manera podemos definir dos flags más que tiene tipos cadena (str) y binario (bool).

var (
    strFlag = flag.String("str", "default", "mensaje de ayuda")
    boolFlag= flag.Bool("bool", false, "mensaje de ayuda")
)

También lo podemos hacer al estilo Go, vinculando las variables con la función específica para cada tipo de dato:

var (
    intFlag int
    strFlag string
    boolFlag bool
)

func main() {
	flag.IntVar(&intFlag, "int", 123, "help message")
	flag.StringVar(&strFlag, "str", "default" , "help message")
	flag.BoolVar(&boolFlag, "bool", false, "help message")
}

Especificar los flags

En la línea de comandos se pueden utilizar diferentes maneras de especificar los flags:

-flag
--flag   // el doble guión también está permitido
-flag=x
-flag x  // esta forma solo para los que no son de tipo booleano

Ejemplo. Creamos un programa para poner a prueba los argumentos que le podemos pasar a un programa utilizando este paquete.

package main

import (
 "flag"
 "fmt"
)

// (1)
var(
    intFlag int
    strFlag string
    boolFlag bool
)

func main() {
	// (2)
	flag.IntVar(&intFlag, "int", 1234, "argumento de tipo entero")
	flag.StringVar(&strFlag, "str", "default" , "argumento de tipo cadena")
	flag.BoolVar(&boolFlag, "bool", false, "argumento binario")

	// (3)
	flag.Parse()
	
	fmt.Println("intFlag = ", intFlag)
	fmt.Println("strFlag = ", strFlag)
	fmt.Println("boolFlag = ", boolFlag)
}

1. Declaramos tres variables: `intFlag`, `strFlag` y `boolFlag`. Estas variables contendrán los valores de los indicadores de línea de comandos correspondientes.

2. Usamos las funciones `flag.IntVar`, `flag.StringVar` y `flag.BoolVar` para definir los indicadores y asociarlos con las variables.

3. Después de definir los indicadores, se llama a la función `flag.Parse()` para analizar los argumentos de la línea de comandos y establecer los valores de las variables correspondientes. Se debe llamar después de que se definan todos los indicadores y antes de que el programa acceda a ellos, para que se puedan realizar el análisis gramatical.

Ahora sin flags

Si ejecutamos este programa sin ninguna bandera, utilizará los valores predeterminados para las variables.

go run .\main.go
intFlag =  123
strFlag = default
boolFlag = false

A continuación, enviamos flags y podemos ver cómo se han procesado.

go run .\main.go -int 42 -str hola! -bool=true
intFlag value is:  42
strFlag value is:  hola!
boolFlag value is:  true

Ayuda

También puedes ejecutar un flag -h, -help para listar los mensajes de ayuda de los flags definidos. Este flag viene definido en el paquete, no es necesario codificar nada.

go run .\main.go -help
Usage of \go-..\main.exe:
  -bool
        argumento de binario
  -int int
        argumento de tipo entero
  -str string
        argumento de tipo cadena

Se puede modificar la salida para que no aparezca la primera línea:

flag.Usage = func() {
	fmt.Fprintln(os.Stderr, "Flags:")
	flag.PrintDefaults()
}

Slice de cadena

Si queremos la lista de argumentos en un slice de string, como lo hace el paquete estándar os.Args, podemos utilizar la función flags.Args(). Pero aquí se recogen solo los que no son de tipo flag.

fmt.Println("Todos los argumentos:", os.Args)
fmt.Println("Argumentos que no son flags:", flag.Args())

Importante

Flags requiere que los parámetros de tipo flag estén antes que los argumentos que no son flags, porque ignora los flags que vienen después del resto de argumentos propios del programa. Es decir:

go run .\main.go arg1 arg2 arg3 -int 1 -str hello -bool=true
Todos los argumentos [\main.exe arg1 arg2 arg3 -int 1 -str hello -bool=true]
Argumentos que no son flags: [arg1 arg2 arg3 -int 1 -str hello -bool=true]

intFlag =  123
strFlag = default
boolFlag = false
Referencias
Xavier es un desarrollador senior full stack y opera desde la ciudad mediterránea de Barcelona. Le encantan las tecnologías de software y está convencido que el desarrollo de software es un proceso colaborativo y abierto.
Y es un apasionado de la astronomía y de la fotografía. Lo puedes encontrar en:
Comparte este post