2013-10-27 2 views
10

Я хотел бы запустить свою программу, как это:Golang Флаг получает интерпретируется как первый аргумент os.Args

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

Я уверен, что это должно быть возможно, но я не могу понять, каким образом.

EDIT: Спасибо justinas за подсказку с флагом.Args(). Теперь я приспособил это так и работает:

... 
flag.Parse() 

args := flag.Args() 
    if len(args) != 1 { 
     log.Fatal("Only one argument (URL) allowed.") 
    } 

page := model.NewBasePage(args[0]) 
... 

ответ

20

os.Args не знает ничего о flag пакете и содержит все аргументы командной строки. Попробуйте flag.Args() (после звонка flag.Parse(), конечно).

+3

Не похоже, чтобы работать с моей программой. Если перед флагом есть аргумент, он просто не будет читать флаг, независимо от того, используете ли вы флаги.Args() и 'flag.Parse()'. – mmstick

11

В последующем наблюдении, разобрать флаги, которые следуют за командой, как

runme init -m thisis 

Вы можете создать свой собственный flagset пропустить первое значение как

var myValue string 
mySet := flag.NewFlagSet("",flag.ExitOnError) 
mySet.StringVar(&myValue,"m","mmmmm","something") 
mySet.Parse(os.Args[2:]) 
0

Вы можете проверить, если Arg начинается с «-» или «-» и избегать использования этого Arg в цикле.

Например:

for _, file := range os.Args[1:] { 
    if strings.HasPrefix(file, "--") { 
     continue 
    } 
    //do stuff 
    } 
Смежные вопросы