Creating Simple Command-Line Tools in Go

Tutorial 1 of 5

Creating Simple Command-Line Tools in Go

1. Introduction

In this tutorial, we will explore how to create simple command-line tools in Go. These tools are also known as CLI (Command Line Interface) applications. CLI tools are often used for automating tasks, processing files, and managing system resources.

By the end of this tutorial, you will be able to:
- Understand the basics of CLI applications
- Implement CLI tools using Go
- Create your own command-line applications in Go

This tutorial assumes you have a basic understanding of programming concepts and have Go installed on your machine.

2. Step-by-Step Guide

Go is a fantastic language for creating CLI tools due to its simplicity and efficient compilation. We will use the flag package from the Go standard library to parse command-line arguments.

Creating a Basic CLI Program

Here's a simple Go program that can be run from the command line:

package main

import (
    "fmt"
    "os"
)

func main() {
    args := os.Args
    fmt.Println(args)
}

In this code, os.Args is a slice that contains all command-line arguments. The first item, os.Args[0], is the name of the program itself. The following items are the arguments that were given to the program.

Using the flag Package

The flag package provides a more robust way to parse command-line arguments. Here's an example:

package main

import (
    "flag"
    "fmt"
)

func main() {
    name := flag.String("name", "World", "a string")

    flag.Parse()

    fmt.Printf("Hello, %s!\n", *name)
}

In this example, we're defining a new string flag with flag.String("name", "World", "a string"). The flag.String function returns a string pointer.

3. Code Examples

Example 1: Basic Flag Parsing

package main

import (
    "flag"
    "fmt"
)

func main() {
    // Define a new string flag
    name := flag.String("name", "World", "a name to say hello to")
    // Parse the flags
    flag.Parse()
    // Print the value of the flag
    fmt.Printf("Hello, %s!\n", *name)
}

When you run go run main.go -name=Go, the output will be Hello, Go!.

Example 2: Multiple Flags

Here's an example with multiple flags:

package main

import (
    "flag"
    "fmt"
)

func main() {
    name := flag.String("name", "World", "a name to say hello to")
    age := flag.Int("age", 25, "an age")

    flag.Parse()

    fmt.Printf("Hello, %s! You are %d years old.\n", *name, *age)
}

When you run go run main.go -name=Go -age=10, the output will be Hello, Go! You are 10 years old..

4. Summary

In this tutorial, you've learned how to create simple command-line tools in Go. You've learned how to parse command-line arguments using both os.Args and the flag package.

Moving forward, you can explore more advanced features of the flag package and other packages for creating CLI tools, such as cobra.

5. Practice Exercises

  1. Exercise 1: Create a command-line tool that adds together two numbers passed as flags.
  2. Exercise 2: Extend the tool above to support addition, subtraction, multiplication, and division.
  3. Exercise 3: Create a tool that reads a file passed as a flag and prints its contents.

Solutions

  1. Solution to Exercise 1:
package main

import (
    "flag"
    "fmt"
)

func main() {
    num1 := flag.Float64("num1", 0, "first number")
    num2 := flag.Float64("num2", 0, "second number")

    flag.Parse()

    fmt.Printf("The sum is: %.2f\n", *num1 + *num2)
}
  1. Solution to Exercise 2:
package main

import (
    "flag"
    "fmt"
)

func main() {
    num1 := flag.Float64("num1", 0, "first number")
    num2 := flag.Float64("num2", 0, "second number")
    op := flag.String("op", "+", "operation")

    flag.Parse()

    switch *op {
    case "+":
        fmt.Printf("The sum is: %.2f\n", *num1 + *num2)
    case "-":
        fmt.Printf("The difference is: %.2f\n", *num1 - *num2)
    case "*":
        fmt.Printf("The product is: %.2f\n", *num1 * *num2)
    case "/":
        fmt.Printf("The quotient is: %.2f\n", *num1 / *num2)
    default:
        fmt.Println("Unsupported operation")
    }
}
  1. Solution to Exercise 3:
package main

import (
    "flag"
    "fmt"
    "io/ioutil"
    "log"
)

func main() {
    filename := flag.String("file", "", "file to read")

    flag.Parse()

    data, err := ioutil.ReadFile(*filename)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Contents of the file:\n%s", data)
}

Keep practicing and exploring Go's capabilities to create complex CLI tools. Happy coding!