How to print all the flags passed to a go program? [duplicate] - go

This question already has answers here:
How to access command-line arguments passed to a Go program?
(6 answers)
Closed 2 years ago.
I would like to log all the flags(cmdline args) passed to a program at startup. How do I do this? Currently the program uses flag package to read the flags into the program .

If you're using the flag package, there is the concept of a "flag" which is a defined command line argument i.e.
name := flag.String("name", "default", "some name")
And also the concept of an "arg" which is an undefined command line argument (i.e. not a flag).
You can get the list of args with flag.Args() which returns string[].
There doesn't seem to be a way to get the list of flags. There are Visit functions. You could use VisitAll that takes a function to execute on each flag:
flag.VisitAll(func(f *flag.Flag) {
fmt.Printf("%s: %s\n", f.Name, f.Value)
})

You can use os.Args, which is a slice of strings, from the os package.
E.g:
package main
import (
"log"
"os"
)
func main() {
log.Println(os.Args)
}

Related

Golang r.URL.Query("x") does not return the full value with special characters [duplicate]

This question already has answers here:
Characters allowed in GET parameter
(7 answers)
Closed 9 months ago.
I was using r.URL.Query("model") to retrieve a url param. Lets say "https://example.com?model=345;1"
My expected behaviour is to retrieve: 345;1
But I only receive: 345
Is there a specific meaning behind it? and how i can force to get the full value. I am quite new go.
Code example
As LeGEC indicated the problem is due the fact that the semi-colon (;) is a character that has (or could have) special meaning in URLs.
You can use "%#v" in your Go Printf example to see how Go parsed the query string:
package main
import "fmt"
import "net/url"
import "log"
func main() {
u, err := url.Parse("https://example.com?model=345;1")
if err != nil {
log.Fatal(err)
}
q := u.Query()
fmt.Printf("%#v",q)
}
Gives
url.Values{"1":[]string{""}, "model":[]string{"345"}}
You could use u.RawQuery to get the entire string "model=345;1" and then parse it yourself. Not ideal, but perhaps a quick workaround.

How do I make a GO program wait until there is user input? [duplicate]

This question already has answers here:
How can I read from standard input in the console?
(12 answers)
Closed 7 years ago.
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
fmt.Println("insert y value here: ")
input := bufio.NewScanner(os.Stdin)
fmt.Println(input.Text)
}
How do I make the program wait, until the user inputs data?
Scanner isn't really ideal for reading command line input (see the answer HectorJ referenced above), but if you want to make it work, it's a call to Scan() that you're missing (also note that Text() is a method call):
func main() {
fmt.Print("insert y value here: ")
input := bufio.NewScanner(os.Stdin)
input.Scan()
fmt.Println(input.Text())
}

How to get executing code's file's name in go? [duplicate]

This question already has answers here:
Is there a way to get the source code filename and line number in Go?
(1 answer)
Find the path to the executable
(3 answers)
Closed 7 years ago.
Say I have a file:
i_want_this_name.go:
package main
func main(){
filename := some_func() // should be "i_want_this_name"
}
How do I get the executing code's file's name in go?
The name of the command can be found in os.Args[0] as states in the documentation for the os package:
var Args []string
Args hold the command-line arguments, starting with the program name.
To use it, do the following:
package main
import "os"
func main(){
filename := os.Args[0]
}
This should work for you:
package main
import (
"fmt"
"runtime"
)
func main() {
_, fileName, lineNum, _ := runtime.Caller(0)
fmt.Printf("%s: %d\n", fileName, lineNum)
}

How to pass a flag to a command in go lang?

I have been trying to run a command and parse the output in golang. Here is a sample of what I am trying to do:
package main
import (
"fmt"
"os/exec"
)
func main() {
out,err := exec.Command("ls -ltr").Output()
if err != nil {
fmt.Println("Error: %s", err)
}
fmt.Printf("%s",out)
}
Now, when I am trying to run "ls -ltr", I get this error:
Error: %s exec: "ls -ltr": executable file not found in $PATH
So, basically go is looking for whole "ls -ltr" in PATH. And it's not there obviously. Is there any way I can pass a flag to any argument?TIA.
You pass arguments to the program by passing more arguments to the function - it's variadic:
out,err := exec.Command("ls","-ltr").Output()
https://golang.org/pkg/os/exec/#Command
This is a pretty common convention with exec-style functions which you will see in most languages. The other common pattern is builders.
Sometimes the layout of arguments you need to pass won't be known at compile-time (though it's not a good idea to send arbitrary commands to the system - stay safe!). If you want to pass an unknown number of arguments, you can use an array with some special syntax:
// Populate myArguments however you like
myArguments := []string{"bar","baz"}
// Pass myArguments with "..." to use variadic behaviour
out,err := exec.Command("foo", myArguments...).Output()

Explanation of Flags in Go

Can anyone explain flags in Go?
flag.Parse()
var omitNewline = flag.Bool("n", false, "don't print final newline")
flags are a common way to specify options for command-line programs.
package main
import (
"flag"
"fmt"
)
var (
env *string
port *int
)
// Basic flag declarations are available for string, integer, and boolean options.
func init() {
env = flag.String("env", "development", "a string")
port = flag.Int("port", 3000, "an int")
}
func main() {
// 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. *evn to
// get the actual option values.
fmt.Println("env:", *env)
fmt.Println("port:", *port)
}
Run Programs:
go run main.go
Try out the run program by first giving it without flags. Note that if you omit flags they automatically take their default values.
go run command-line-flags.go --env production --port 2000
If you provide a flag with specified value then default will overwrite by passed one.
See http://golang.org/pkg/flag/ for a full description.
The arguments for flag.Bool are (name string, value bool, usage string)
name is the argument to look for, value is the default value and
usage describes the flag's purpose for a -help argument or similar, and is displayed with flag.Usage().
For more detailed example check here
flag is used to parse command line arguments. If you pass "-n" as a command line argument, omitNewLine will be set to true. It's explained a bit farther in the tutorial :
Having imported the flag package, line 12 creates a global variable to hold the value of echo's -n flag. The variable omitNewline has type *bool, pointer to bool.
Personally, I prefer the Var type functions, as they take a reference, rather
than returning a reference. That way you can use the variable without
dereferencing:
package main
import "flag"
func main() {
var omitNewline bool
flag.BoolVar(&omitNewline, "n", false, "don't print final newline")
flag.Parse()
println(omitNewline)
}
https://golang.org/pkg/flag#BoolVar

Resources