How to use the flag pack in Go | to use Digital Ocean (2023)


Command-line tools are rarely usable right away without additional configuration. Good defaults are important, but useful tools must accept user configuration. On most platforms, command-line utilities accept flags to customize how the command is executed. Flags are key-value separated strings appended after the command name. Go allows you to create command line tools that accept flags using theflagpackage from the standard library.

In this tutorial you will learn different ways to use itflagPackage for building various types of command line tools. You use a flag to control program output, introduce positional arguments by mixing flags and other data, and then implement subcommands.

Using a flag to change the behavior of a program

Use offlagThe package consists of three steps: First,Define variablesNext, to collect flag values, define the flags your Go application will use and finally analyze the flags provided to the application when it runs. Most functions within theflagThe package is all about defining flags and binding them to variables you define. The parse phase is handled byparse()Function.

To illustrate, create a program that displays aBoolean valueFlag that changes the printed message to standard output. if there is one-ColourIf you use the flag, the program will issue a blue message. If no flag is specified, the message will print colorless.

Create a new file namedboolean.go:

  1. Nanoboolean.go

Add the following code to the file to create the program:


packagein the first placeimport ("Flag"„fmt“)TypColourstringconst (ColorBlack color= „\u001b[30m“Red colour= „\u001b[31m“color green= "\u001b[32m"color yellow= „\u001b33m“Color blue= \u001[34m]Farbreset= „\u001b[0m“)function colorize(color color,Newsstring) {fmt.print lines(string(Colour),News, string(Farbreset))}function in the first place() {use Color:=flag.Boos("Colour", INCORRECT, "Show colored output")flag.Analyzing()If *use Color{colorize(Color blue, "Hello, DigitalOcean!")return}fmt.print lines("Hello, DigitalOcean!")}

This example usesANSI escape sequencesto instruct the terminal to display colored output. Since these are special strings, it makes sense to define a new type for them. In this example, we called this typeColourand defined the type as onestring. Next, we define a color palette that is in theconstblock that follows. ThecolorizeFunction defined afterconstBlock accepts one of theseColourconstants and onestringVariable for the message to be colored. It then tells the terminal to change color by first printing the escape sequence for the requested color, then printing the message, and finally telling the terminal to reset the color by printing the special color reset sequence.

Insidein the first place, we use thatflag.BoolFunction to define a boolean flag nameColour. The second parameter of this function,INCORRECT, sets the default value for this flag if not specified. Against your odds, you set this upWHEREdoes not reverse the behavior, so if you specify a flag it will become false. Consequently, the value of this parameter is almost alwaysINCORRECTwith boolean flags.

The last parameter is a documentation string that can be printed as a usage report. The value returned by this function is a reference to abunch. Offlag.ParseThe function on the next line uses this pointer to find thebunchVariable based on the flags passed by the user. We can then check the valuebunchPointer by unreferencing the pointer. For more information about pointer variables, see thePointer Guide. With this boolean value we can then callcolorizeif that-Colourflag is set and call thatfmt.PrintlnVariable if flag is absent.

(Video) Build, Deploy, and Scale Your First Web App Using DigitalOcean App Platform

Save the file and run the program without flags:

  1. Run boolean.go

You will see the following output:


Hello DigitalOcean!

Now run this program again with the-ColourFlag:

  1. Run boolean.go-Colour

The output is the same text, but this time in blue.

Flags are not the only values ​​passed to commands. You can also send file names or other data.

Working with positional arguments

Commands usually have a set of arguments that serve as the subject of the command's focus. For example theKopfThe command that prints the first few lines of a file is often called asKopf example.txt. The fileexample.txtis a positional argument when calling theKopfCommando.

Ofparse()The function continues to analyze flags it encounters until it encounters a non-flag argument. TheflagThe package makes these available through theArguments()Inarg()functions.

To demonstrate this, create a simplified redeployment ofKopfCommand that shows the first few lines of a specific file:

Create a new file namedhead.goand add the following code:

(Video) How to Deploy a Resilient Go Application to Kubernetes on DigitalOcean


packagein the first placeimport („bufio“"Flag"„fmt“"io"„os“)function in the first place() {Warto countintflag.IntVar(&to count, "N", 5, "Number of lines to read from file")flag.Analyzing()Warin me.ReaderIffilenames:=flag.Arg(0);filenames!= „“ {F,wrong:=os.Open(filenames)Ifwrong!= Nul {fmt.print lines("Error opening file: Error:",wrong)os.Exit(1)}DelayF.Close to()In=F} anders {In=os.Standard}buf:=bufio.Neuer scanner(In)forI:= 0;I<to count;I++ {If !buf.Scan() {pause}fmt.print lines(buf.Text())}Ifwrong:=buf.wrong();wrong!= Nul {fmt.Fprintln(os.Stderr, "Error reading: Error:",wrong)}}

First we define ato countVariable containing the number of lines the program should read from the file. Then we define the-Nuse flagflag.IntVar, which mirrors the behavior of the originalKopfProgram. This function allows us to pass ourspointerto a variable as opposed toflagFeatures that don'tWarSuffix. Other than this difference, so are the rest of the parametersflag.IntVarfollow himvlag.IntMatch: The flag name, a default value, and a description. Just like in the previous example, we then make a callflag.Parse()to process user input.

The next section reads the file. We define one firstio.ReaderVariable set to the file requested by the user or to standard input passed to the program. Within theIfExplanation, we use thevlag.ArgFunction to access the first positional argument after all flags. If the user provided a file name, it will be set. Otherwise it's the empty string („“). If a filename exists, we use itos.OpenFunction to open this file and theio.ReaderWe have defined this file before. Otherwise we useos.Stdinreading standard input.

The last part uses a*bufio.Scannermade withbufio.NewScannerread lines fromio.ReaderVariableIn. We iterate to the value ofto countmake use of onefor loop, to call to actionpauseif you scan the line withbuf.Scangenerates oneINCORRECTValue indicating that the number of rows is less than the number requested by the user.

Run this program and view the contents of the file you just wrotehead.goas an argument:

  1. ga rennen head.go -- head.go

Of--Delimiter is a special flag recognized byflagPacket indicating that no further flag arguments follow. When you run this command, you get the following output:


Package mainimport ("bufio" "vlag"

Use the-NFlag you defined to adjust the output amount:

  1. ga rennen head.go-N 1head.go

This only displays the package statement:


(Video) Lisa Lisa & Cult Jam, Full Force - I Wonder If I Take You Home (Official Music Video)

Play pack

Finally, when the program realizes that no positional arguments have been provided, it reads the standard input as followsKopf. Try running this command:

  1. Echo "Vis\NHummer\NBind\NElritzen" |ga rennen head.go-N 3

You see the output:


Fish Cancer Sharks

The behavior offlagThe features you've seen so far are limited to examining the entire command call. You don't always want this behavior, especially if you're writing a command-line program that supports subcommands.

Use FlagSet to implement subcommands

Modern command line applications often implement "subcommands" to bundle a set of tools under one command. The most popular tool using this pattern isIdiot. When researching a command such asgit begin,Idiotis the command andinsideis the sub-command ofIdiot. A notable feature of subcommands is that each subcommand can have its own set of flags.

Go applications can support subcommands with their own set of flagsFlag.(*FlagSet)Type. To demonstrate this, create a program that implements a command using two subcommands with different flags.

Create a new file namedsubcommando.goand add the following content to the file:

packagein the first placeimport ("Wrong""Flag"„fmt“„os“)function NewGreetCommand() *GreetCommand{gc:= &GreetCommand{fs:flag.NewFlagSet("regards",flag.ContinueOnError),}gc.fs.StringVar(&gc.Name, "Name", "Welt", "Name of person to be greeted")returngc}TypGreetCommandStructure {fs*flag.FlagSet namestring}function (G*GreetCommand) Name() string {returnG.fs.Name()}function (G*GreetCommand) inside(arguments[]string) Wrong {returnG.fs.Analyzing(arguments)}function (G*GreetCommand) Loop() Wrong {fmt.print lines("Hallo",G.Name, „!“)return Nul}Typrunnerkoppel {inside([]string) WrongLoop() WrongName() string}function carrot(arguments[]string) Wrong {If to borrow(arguments) < 1 {returnWrong.New("You must pass a subcommand")}cmds:= []runner{NewGreetCommand(),}under command:=os.argument[1]for _,cmd:= Areacmds{Ifcmd.Name() ==under command{cmd.inside(os.argument[2:])returncmd.Loop()}}returnfmt.wrong("Unknown subcommand: %s",under command)}function in the first place() {Ifwrong:= carrot(os.argument[1:]);wrong!= Nul {fmt.print lines(wrong)os.Exit(1)}}

This program is divided into a number of parts: thein the first placefunction thatcarrotFunction and the individual functions that implement the subcommand. Thein the first placeThe function handles errors returned by commands. When a function returns aWrong, DieIfThe statement catches it, prints the error, and the program exits with the status code1, indicating that the rest of the operating system has encountered an error. Insidein the first placewe pass all the arguments with which the program was calledcarrot. We remove the first argument, the name of the program (in the previous examples)../subcommando) by cuttingde.ArgsFirst.

Ofcarrotfunction defined[] Renner, where all subcommands would be defined.runneris akoppelfor subcommands that allow itcarrotto get the name of the subcommandName()and compare it with the contentunder commandVariable. After after iteration the correct subcommand is foundcmdsVariably, we initialize the subcommand with the remaining arguments and call the commandsLoop()Method.

We only define one subcommand, although we could easily create more with this framework. TheGreetCommandis instantiated withNewGreetCommandwhere we create something new*flag.FlagSetuseflag.NewFlagSet.flag.NewFlagSettakes two arguments: a name for the set flag and a strategy for reporting parsing errors. The*flag.FlagSetThe name can be accessed through theflag.(*FlagSet).NameMethod. We use this in the(*GreetCommand).Name()method to make the name of the subcommand match the name we gave it*flag.FlagSet.NewGreetCommandalso defines one-NameMark in a similar way to the previous examples, but instead call this a method outside the*flag.FlagSetarea of*Greet Commando,gc.fs. Ifcarrotcalls theInside()method of*Greet Commando, we pass the specified arguments to theAnalyzingmethod of*flag.FlagSetveld.

(Video) Handyman Tips & Hacks That Work Extremely Well ▶3

Subcommands are easier to spot if you build and then run this program. Create the program:

  1. Go to create subcommand.go

Now run the program without arguments:

  1. ./subcommando

You see this output:


You must pass a subcommand

Now run the program with theregardssubcommand:

  1. ./salute subcommand

This produces the following output:


Hello World !

Now use the-Nameflag alongregardsTo specify a name:

  1. ./salute subcommand-Name Sammy

You will see this output from the program:


(Video) Rich The Kid - Plug Walk


This example illustrates some of the principles behind how to structure larger command-line applications in Go.Flag sets are intended to give developers more control over where and how flags are processed by the flag parsing logic.


Flags make your applications more useful in more contexts because they give your users control over how the programs run. It's important to give users convenient default settings, but you also need to give them the option to ignore settings that don't work for their situation. You saw thatflagThe package provides flexible ways to present configuration options to your users. You can choose a few simple flags or create an expandable set of sub-commands. In both cases, use theflagThe package helps you build tools in the style of the long history of flexible and scriptable command-line tools.

Check out our complete guide to learn more about the Go programming languageSeries "How to code in Go"..


1. This is a Morphed Axolotl 🦎
(Aquarium Info)
2. Dokku Deploy NodeJS with HTTPS on Digital Ocean - Part 20
(Lester Fernandez)
3. Live 58 · Serving Apps in DigitalOcean w/ Custom Domains & Live Hacks
(Nono Martínez Alonso)
4. Install WordPress On A Digital Ocean VPS Droplet
(The Polyglot Developer)
5. The Pharcyde - Passin' Me By (Official Music Video)
6. Skylar Grey - Love The Way You Lie (Live on the Honda Stage at The Peppermint Club)
(Skylar Grey)


Top Articles
Latest Posts
Article information

Author: Clemencia Bogisich Ret

Last Updated: 08/18/2023

Views: 6464

Rating: 5 / 5 (80 voted)

Reviews: 95% of readers found this page helpful

Author information

Name: Clemencia Bogisich Ret

Birthday: 2001-07-17

Address: Suite 794 53887 Geri Spring, West Cristentown, KY 54855

Phone: +5934435460663

Job: Central Hospitality Director

Hobby: Yoga, Electronics, Rafting, Lockpicking, Inline skating, Puzzles, scrapbook

Introduction: My name is Clemencia Bogisich Ret, I am a super, outstanding, graceful, friendly, vast, comfortable, agreeable person who loves writing and wants to share my knowledge and understanding with you.