From de13d94a820fd2b7d3af106c1d1042c277861b3d Mon Sep 17 00:00:00 2001 From: Mark McGranaghan Date: Mon, 22 Oct 2012 09:34:34 -0400 Subject: [PATCH] publish command-line-arguments and command-line-flags --- examples.txt | 4 +- .../command-line-arguments.go | 19 +++--- .../command-line-arguments.sh | 13 ++-- .../command-line-flags/command-line-flags.go | 54 +++++++++++++---- .../command-line-flags/command-line-flags.sh | 59 +++++++++++++++++++ templates/site.css | 1 - 6 files changed, 121 insertions(+), 29 deletions(-) create mode 100644 examples/command-line-flags/command-line-flags.sh diff --git a/examples.txt b/examples.txt index f5eba8f..f2eda07 100644 --- a/examples.txt +++ b/examples.txt @@ -60,8 +60,8 @@ SHA1 Hashes # Reading Files # Writing Files Line Filters -# Command-Line Arguments -# Command-Line Flags +Command-Line Arguments +Command-Line Flags Environment Variables Spawning Processes Exec'ing Processes diff --git a/examples/command-line-arguments/command-line-arguments.go b/examples/command-line-arguments/command-line-arguments.go index 875fe9f..275a6f7 100644 --- a/examples/command-line-arguments/command-line-arguments.go +++ b/examples/command-line-arguments/command-line-arguments.go @@ -1,23 +1,26 @@ -// Use `os.Args` to access command-line arguments and -// the name of the program. +// [_Command-line arguments_](http://en.wikipedia.org/wiki/Command-line_interface#Arguments) +// are a common way to parameterize execution of programs. +// For example, `go run hello.go` uses `run` and +// `hello.go` arguments to the `go` program. + package main import "os" import "fmt" func main() { - // `os.Args` includes the program name as the first - // value. + + // `os.Args` provides access to raw command-line + // arguments. Note that the first value in this slice + // is the path to the program, and `os.Args[1:]` + // holds the arguments to the program. argsWithProg := os.Args argsWithoutProg := os.Args[1:] - // `Args` are a slice, you can get individual args - // with normal indexing. + // You can get individual args with normal indexing. arg := os.Args[3] fmt.Println(argsWithProg) fmt.Println(argsWithoutProg) fmt.Println(arg) } - -// todo: discuss building before here diff --git a/examples/command-line-arguments/command-line-arguments.sh b/examples/command-line-arguments/command-line-arguments.sh index 66977b8..b79d8b3 100644 --- a/examples/command-line-arguments/command-line-arguments.sh +++ b/examples/command-line-arguments/command-line-arguments.sh @@ -1,9 +1,10 @@ -# Build a `command-line-args` binary so that we have -# the expected program name. -$ go build command-line-arguments - - +# To experiment with command-line arguments it's best to +# build a binary with `go build` first. +$ go build command-line-arguments.go $ ./command-line-arguments a b c d -[command-line-arguments a b c d] +[./command-line-arguments a b c d] [a b c d] c + +# Next we'll look at more advanced command-line processing +# with flags. diff --git a/examples/command-line-flags/command-line-flags.go b/examples/command-line-flags/command-line-flags.go index b0a0249..af4f8a7 100644 --- a/examples/command-line-flags/command-line-flags.go +++ b/examples/command-line-flags/command-line-flags.go @@ -1,19 +1,49 @@ +// [_Command-line flags_](http://en.wikipedia.org/wiki/Command-line_interface#Command-line_option) +// are a common way to specify options for command-line +// programs. For example, in `wc -l` the `-l` is a +// command-line flag. + package main +// Go provides a `flag` package supporting basic +// command-line flag parsing. We'll use this package to +// implement our example command-line program. import "flag" import "fmt" func main() { - maxp := flag.Int("repeat", 3, "time to repeat args") - flag.Parse() - for i := 0; i < *maxp; i++ { - for _, arg := range flag.Args() { - fmt.Println(arg) - } - } -} -// todo: multiple flags -// todo: trailing args -// todo: arg escaping -// todo: help text and usage errors + // Basic flag declarations are available for string, + // integer, and boolean options. Here we declare a + // string flag `word` with a default value `"foo"` + // and a short description. This `flag.String` function + // returns a string pointer (not a string value); + // we'll see how to use this pointer below. + wordPtr := flag.String("word", "foo", "a string") + + // This declares `numb` and `fork` flags, using a + // similar approach to the `word` flag. + numbPtr := flag.Int("numb", 42, "an int") + boolPtr := flag.Bool("fork", false, "a bool") + + // It's also possible to declare an option that uses an + // existing var declared elsewhere in the program. + // Note that we need to pass in a pointer to the flag + // declaration function. + var svar string + flag.StringVar(&svar, "svar", "bar", "a string var") + + // Once all flags are declared, call `flag.Parse()` + // to execute the command-line parsing. + flag.Parse() + + // Here we'll just dump out the parsed options and + // any trailing positional arguments. Note that we + // need to dereference the points with e.g. `*wordPtr` + // to get the actual option values. + fmt.Println("word:", *wordPtr) + fmt.Println("numb:", *numbPtr) + fmt.Println("fork:", *boolPtr) + fmt.Println("svar:", svar) + fmt.Println("tail:", flag.Args()) +} diff --git a/examples/command-line-flags/command-line-flags.sh b/examples/command-line-flags/command-line-flags.sh new file mode 100644 index 0000000..8b22c06 --- /dev/null +++ b/examples/command-line-flags/command-line-flags.sh @@ -0,0 +1,59 @@ +# To experiment with the command-line flags program it's +# best to first compile it and then run the resulting +# binary directly. +$ go build command-line-flags.go + +# Try out the built program by first giving it values for +# all flags. +$ ./command-line-flags -word=opt -numb=7 -fork -svar=flag +word: opt +numb: 7 +fork: true +svar: flag +tail: [] + +# Note that if you omit flags they automatically take +# their default values. +$ ./command-line-flags -word=opt +word: opt +numb: 42 +fork: false +svar: bar +tail: [] + +# Trailing positional arguments can be provided after +# any flags. +$ ./command-line-flags -word=opt a1 a2 a3 +word: opt +... +tail: [a1 a2 a3] + +# Note that the `flag` package requires all flags to +# appear before positional arguments (otherwise the flags +# will be interpreted as positional arguments). +$ ./command-line-flags -word=opt a1 a2 a3 -num=7 +word: opt +numb: 42 +fork: false +svar: bar +trailing: [a1 a2 a3 -num=7] + +# Use `-h` or `--help` flags to get automatically +# generated help text for the command-line program. +$ ./command-line-flags -h +Usage of ./command-line-flags: + -fork=false: a bool + -numb=42: an int + -svar="bar": a string var + -word="foo": a string + +# If you provide a flag that wasn't specified to the +# `flag` package, the program will print an error message +# an show the help text again. +$ ./command-line-flags -wat +flag provided but not defined: -wat +Usage of ./command-line-flags: +... + +# Next we'll look at environment variables, another common +# way to parameterize programs. diff --git a/templates/site.css b/templates/site.css index a798934..bbe6329 100644 --- a/templates/site.css +++ b/templates/site.css @@ -142,7 +142,6 @@ body .hll { background-color: #ffffcc } body .err { border: 1px solid #FF0000 } /* Error */ body .c { color: #408080; font-style: italic } /* Comment */ body .k { color: #954121 } /* Keyword */ -body .n { color: #954121 } /* Keyword */ body .o { color: #666666 } /* Operator */ body .cm { color: #408080; font-style: italic } /* Comment.Multiline */ body .cp { color: #BC7A00 } /* Comment.Preproc */