5

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)
    }

}

2 Answers 2

24

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.

Sign up to request clarification or add additional context in comments.

Comments

-1

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.

6 Comments

os.Args starts with the program name, so you should check len() > 1. Also no need to test if it's nil (redundant), the builtin len() function works on nil slices as well.
I'm not developing go ;) As I said, my solution is best practice for every array with unkown origin. So when you wanna be clean and correct, do it like I did and ignore that go handle this for you ;)
I don't think that's a very good advice, basically you're saying "forget in which language you're coding, and only use the common subset of all languages". Doing so you will end up unnecessarily complicated, ugly and non-idiomatic code. Also the len() > 1 check is mandatory, checking only len() > 0 you may end up with the same error if no arguments is specified because len() > 1 is always true as Args contains the program name, but if no arguments were specified, Args[1] will result in a : runtime error: index out of range
As you say ;) Keep on go, I keep on applied computer science :D
This will still panic the same way as in the question. len(os.Args) > 0 is always true, and doesn't check for any command line arguments.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.