Golang命令参数为空导致错误。

huangapple go评论76阅读模式
英文:

Golang command arguments empty causing error

问题

我正在写一个Go程序,需要使用命令行参数。然而,如果我在运行可执行文件或go run gosite.go时不传递参数,代码会出现以下运行时错误。

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

错误出现在第11行。所以我的问题是,我是否以错误的方式使用了os.Args?这个需要以不同的方式初始化吗?另外,为什么它似乎在那里进入了一个无限循环?如果我传入一个参数,程序就可以正常运行并打印出参数。

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)
    }
}
英文:

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

}

答案1

得分: 22

首先检查os.Args切片的长度,并且只索引到长度减1的位置:

if len(os.Args) > 1 {
    command := os.Args[1]
    // 使用command做一些操作
} else {
    // 没有指定参数!
}

os.Args保存了命令行参数,从程序名称开始。

os.Args[0]是程序名称。如果有参数,它们会依次存储在Args[1]Args[2]等位置。

如果没有指定参数,os.Args的长度将为1,并且只包含程序名称。

另外,为了更方便和更复杂的参数处理,请查看flag包。

英文:

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.

答案2

得分: -1

在访问os.Args之前,你需要首先检查它是否存在以及其大小。这是在任何编程语言中使用数组的最佳实践。

以下代码应该可以工作:

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

根据所有那些挑剔的人的意见,只有他们才能继续,并且已经阅读了这里正确处理输入参数的手册。请注意,我之前说过,我不开发Go语言,我只是根据处理数组的最佳实践进行回答,以避免超出范围的错误。

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. 不再检查nil,因为os.Args始终被初始化,并且在索引0处保存应用程序名称。
  2. 它检查len大于1,以确保索引1存在。换句话说,用户输入了参数,并且os.Args除了应用程序名称之外还有更多条目。
英文:

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.

huangapple
  • 本文由 发表于 2015年5月18日 19:28:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/30302017.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定