zachdyer
zachdyer

Reputation: 611

Golang command arguments empty causing error

I'm writing a go program and I need to use command arguments. However if I don't pass arguments when I run the executable or go run gosite.go the code it does the following runtime error.

panic: runtime error: index out of range

goroutine 1 [running]:
runtime.panic(0x80c8540, 0x816d4b7)
/usr/lib/go/src/pkg/runtime/panic.c:266 +0xac
main.main()
/home/jacob/github/gosite/src/github.com/zachdyer/gosite/gosite.go:11 +0x168

The error is found on line 11. So my question is am I using the os.Args in the wrong way? Does this need to be initialized in a different way? Also why does it seem to be going in an infinite loop there? If I pass in an argument the program runs without any errors and prints the argument.

import (
    "fmt"
    "os"
)

var root string

func main() {
    command := os.Args[1]
    if command != "" {
        fmt.Println(command)
    } else {
        command = ""
        fmt.Println("No command given")
    }

    createDir("public")
    createDir("themes")
}

func createDir(dir string) {
    root = "../../../../"
    err := os.Mkdir(root + dir, 0777)
    if err != nil {
        fmt.Println(err)
    }

}

Upvotes: 5

Views: 15293

Answers (2)

Rene M.
Rene M.

Reputation: 2690

You have to check first if os.Args exist and how big it is , before you should access it. This is best practive in ervery programming language using arrays.

This should work:

func main() {

    if (os.Args != nil && len(os.Args) > 1) {
        command := os.Args[1]
        if command != "" {
            fmt.Println(command)
        } else {
            command = ""
            fmt.Println("No command given")
        }
    }
    createDir("public")
    createDir("themes")
}

Depending on all that fault-finder's here that only can go, and had readen the handbook here the correct only go specific version for handling the input arguments. (A Note as I sad before, I don't develop go, I answered by best practice for handling arrays, to prefend out of range error):

func main() {

    if (len(os.Args) > 1) {
        command := os.Args[1]
        if command != "" {
            fmt.Println(command)
        } else {
            command = ""
            fmt.Println("No command given")
        }
    }
    createDir("public")
    createDir("themes")
}
  1. It is not checking on nil anymore, because os.Args always are initialized and holds the app name on index 0
  2. It checks the len greater then 1 to make sure that index 1 exist. Or in other words the user has entered arguments and os.Args has more entries then only the app name.

Upvotes: -1

icza
icza

Reputation: 417612

First check the length of the os.Args slice and only index up to its length - 1:

if len(os.Args) > 1 {
    command := os.Args[1]
    // do something with command
} else {
    // No arguments were specified!
}

os.Args hold the command-line arguments, starting with the program name.

os.Args[0] is the program name. If there are arguments, they go to Args[1], Args[2]...

If no arguments were specified, the length of os.Args will be 1 and will hold only the program name.

Also for easier and more sophisticated arguments handling check out the flag package.

Upvotes: 23

Related Questions