我想像这样运行我的程序:
go run launch.go http://example.com --m=2 --strat=par
“http://example.com”被解释为第一个命令行参数,这是正常的,但之后不会解析标志并保持默认值。如果我这样说:
go run launch.go --m=2 --strat=par http://example.com
然后“--m = 2”被解释为第一个参数(应该是URL)。
我也可以完全删除os.Args,但之后我只有可选的标志,我想要一个(URL)是强制性的。
这是我的代码:
package main
import (
"fmt"
"webcrawler/crawler"
"webcrawler/model"
"webcrawler/urlutils"
"os"
"flag"
)
func main() {
if len(os.Args) < 2 {
log.Fatal("Url must be provided as first argument")
}
strategy := flag.String("strat", "par", "par for parallel OR seq for sequential crawling strategy")
routineMultiplier := flag.Int("m", 1, "Goroutine multiplier. Default 1x logical CPUs. Only works in parallel strategy")
page := model.NewBasePage(os.Args[1])
urlutils.BASE_URL = os.Args[1]
flag.Parse()
pages := crawler.Crawl(&page, *strategy, *routineMultiplier)
fmt.Printf("Crawled: %d\n", len(pages))
}
我很确定这应该是可能的,但我无法弄清楚如何。
编辑: 感谢justinas与flag.Args()的提示。我现在像这样适应它并且它有效:
...
flag.Parse()
args := flag.Args()
if len(args) != 1 {
log.Fatal("Only one argument (URL) allowed.")
}
page := model.NewBasePage(args[0])
...
答案 0 :(得分:21)
os.Args
对flag
包没有任何了解,并且包含所有命令行参数。试试flag.Args()(当然,在致电flag.Parse()
之后)。
答案 1 :(得分:12)
作为后续,解析跟随
之类的命令的标志runme init -m thisis
您可以创建自己的标记集以跳过第一个值,如
var myValue string
mySet := flag.NewFlagSet("",flag.ExitOnError)
mySet.StringVar(&myValue,"m","mmmmm","something")
mySet.Parse(os.Args[2:])
答案 2 :(得分:1)
这也使我感到震惊,并且由于我在应用程序中的多个地方调用了flag.String/flag.Int64/etc
,所以我不想在整个地方都经过一个新的flag.FlagSet
。 / p>
// If a commandline app works like this: ./app subcommand -flag -flag2
// `flag.Parse` won't parse anything after `subcommand`.
// To still be able to use `flag.String/flag.Int64` etc without creating
// a new `flag.FlagSet`, we need this hack to find the first arg that has a dash
// so we know when to start parsing
firstArgWithDash := 1
for i := 1; i < len(os.Args); i++ {
firstArgWithDash = i
if len(os.Args[i]) > 0 && os.Args[i][0] == '-' {
break
}
}
flag.CommandLine.Parse(os.Args[firstArgWithDash:])
之所以这样做,是因为flag.Parse
仍然只是在后台调用flag.CommandLine.Parse(os.Args[1:])
。
答案 3 :(得分:0)
您可以检查Arg是否以&#34; - &#34;或&#34; - &#34;并避免在循环中使用该Arg。
例如:
for _, file := range os.Args[1:] {
if strings.HasPrefix(file, "--") {
continue
}
//do stuff
}