Golang命令行参数/标志的用法解析
Golang命令行参数/标志的用法解析 你好,我想使用命令行标志/参数。 例如:
MYSOFT -g FILE
使用 flags.String 时,它能正常工作,但如果我们没有在 -g 标志后传递任何参数,它会显示:
flag needs an argument: -g
Usage of ./MYSOFT:
-g string
(default "install")
我希望如果标志参数为空,它应该显示: 请提供一个参数以进行安装
实际上,我想要的是,如果有人运行 MYSOFT 命令,输出应该像这样:
Usage: <options> software
MYSOFT Options:
-i, --install, install Install Software
You must have the name of the software you want to install or update, so you can use this command.
如果有人运行 MYSOFT -i,那么输出应该像这样:
Please enter any software, the selected software doesn't exists
如果有人运行 MYSOFT -i CALCULATOR
it will execute some codes
我也尝试过通过 os.Args 来实现,但无论怎么做都不太对。
当我通过 fmt.Println 添加这些行时:
Usage: <options> software
MYSOFT Options:
-i, --install, install Install Software
You must have the name of the software you want to install or update, so you can use this command.
那么如果我运行 MYSOFT -i CALCULATOR,上面的字符串也会出现
有人知道该怎么做吗
更多关于Golang命令行参数/标志的用法解析的实战教程也可以访问 https://www.itying.com/category-94-b0.html
所以,我认为你需要寻找像这样的自定义标志解析器:https://github.com/cosiner/flag
问题依旧存在:
当你运行 go run . -i 并且不输入任何内容时,该命令会显示默认的帮助信息并以代码 2 退出。
gucio321:
我发现我的代码有个问题
如果你把默认字符串从 “default” 改成 “” 会怎样?
result.name = flag.String("i", "", "enter app name")
找到了解决方案。FlagSet 结构体包含一个类型为 func() 的 Usage 字段。你可以在这里设置自己的用法信息,如下所示:
fs.Usage = func() {
fmt.Println("Usage: blah...")
}
哦,是的,是我的错。我把不带参数传递 -i 和完全不传递 -i 搞混了。
我猜对于自定义错误处理,使用 FlagSet 可能是一个解决方案。
func main() {
fmt.Println("hello world")
}
哟!
也许像这样? 哦,好吧,我发现我的代码有个问题。
package main
import (
"flag"
"fmt"
)
type Flags struct {
name *string
}
func parse() *Flags {
result := &Flags{}
result.name = flag.String("i", "default", "enter app name")
flag.Parse()
if *result.name == "" {
fmt.Println("you must enter something")
}
return result
}
func main() {
f := parse()
fmt.Println(*f.name)
}
嗯,我觉得当没有提供标志值时,它仍然会打印 Usage()。
我使用 FlagSet 的代码:
package main
import (
"flag"
"fmt"
"os"
)
type Flags struct {
name *string
}
func parse() *Flags {
result := &Flags{}
fs := flag.NewFlagSet("arguments", flag.ContinueOnError)
result.name = fs.String("i", "default", "enter app name")
if err := fs.Parse(os.Args[1:]); err != nil {
fmt.Println(err)
// return result
}
if *result.name == "" {
fmt.Println("you must enter something")
}
return result
}
func main() {
f := parse()
fmt.Println(*f.name)
}
在Go中,你可以通过自定义flag.Usage函数和验证标志值来实现你的需求。以下是一个完整的示例:
package main
import (
"flag"
"fmt"
"os"
)
func main() {
// 自定义usage信息
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage: <options> software\n\n")
fmt.Fprintf(os.Stderr, "MYSOFT Options:\n")
fmt.Fprintf(os.Stderr, " -i, --install, install Install Software\n\n")
fmt.Fprintf(os.Stderr, "You must have the name of the software you want to install or update, so you can use this command.\n")
}
// 定义标志
installFlag := flag.String("i", "", "Install Software")
flag.StringVar(installFlag, "install", "", "Install Software")
// 解析标志
flag.Parse()
// 检查是否只运行了MYSOFT而没有参数
if len(os.Args) == 1 {
flag.Usage()
return
}
// 检查-i标志是否被设置但值为空
if *installFlag == "" && (flagIsSet("i") || flagIsSet("install")) {
fmt.Println("Please enter any software, the selected software doesn't exists")
return
}
// 如果有有效的软件名,执行安装逻辑
if *installFlag != "" {
fmt.Printf("Installing software: %s\n", *installFlag)
// 这里添加你的安装代码
// executeSomeCodes()
}
}
// 辅助函数检查标志是否被设置
func flagIsSet(name string) bool {
found := false
flag.Visit(func(f *flag.Flag) {
if f.Name == name {
found = true
}
})
return found
}
另一个更简洁的实现方式,使用flag.FlagSet:
package main
import (
"flag"
"fmt"
"os"
)
func main() {
// 创建自定义的FlagSet
fs := flag.NewFlagSet("MYSOFT", flag.ExitOnError)
// 设置自定义usage
fs.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage: <options> software\n\n")
fmt.Fprintf(os.Stderr, "MYSOFT Options:\n")
fmt.Fprintf(os.Stderr, " -i, --install, install Install Software\n\n")
fmt.Fprintf(os.Stderr, "You must have the name of the software you want to install or update, so you can use this command.\n")
}
// 定义标志
installFlag := fs.String("i", "", "Install Software")
fs.StringVar(installFlag, "install", "", "Install Software")
// 如果没有参数,显示usage
if len(os.Args) == 1 {
fs.Usage()
return
}
// 解析参数
err := fs.Parse(os.Args[1:])
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
return
}
// 检查安装标志
if (*installFlag == "" && (fs.Lookup("i").Changed || fs.Lookup("install").Changed)) {
fmt.Println("Please enter any software, the selected software doesn't exists")
return
}
// 执行安装逻辑
if *installFlag != "" {
fmt.Printf("Installing software: %s\n", *installFlag)
// 这里添加你的安装代码
}
}
测试示例:
- 运行
MYSOFT:
Usage: <options> software
MYSOFT Options:
-i, --install, install Install Software
You must have the name of the software you want to install or update, so you can use this command.
- 运行
MYSOFT -i:
Please enter any software, the selected software doesn't exists
- 运行
MYSOFT -i CALCULATOR:
Installing software: CALCULATOR
这个实现通过自定义flag.Usage函数控制帮助信息的显示,使用flag.Visit或FlagSet.Lookup().Changed来检查标志是否被设置,并在标志被设置但值为空时显示自定义错误信息。

