It's posting the input twice - go

I want to read some input from stdin and then display it. At the moment I am doing this like this:
in := bufio.NewReader(os.Stdin);
input, err = in.ReadString('\n');
if err != nil {
fmt.Println("Error: ", err)
os.Exit(1)
}
fmt.Printf("This is your", input)
...but after running this and entering some input it is always displaying my input twice like this:
This is just a test
This is your This is just a test
Is there anyway to remove the first line?

I haven't yet tried anything with the package, but I guess it could be helpful in this case: exp/terminal. Specifically the ReadPasword function documentations is:
ReadPassword reads a line of input from a terminal without local echo.
This is commonly used for inputting passwords and other sensitive data.
The slice returned does not include the \n.

I assume your first line is just your echoed input text? That's actually a function of the process' terminal. Since the go runtime treats Stdin like any other file, you don't have direct access to the terminal attributes. However you might be able to hack something together with CGO and the approach described here.

Related

How to take input when outputting?

What I'm trying to achieve is some kind of an application that logs a lot of information into the console (for instance, numbers from 0 to 1000000000000) and an ability to stop the execution by typing a command in the console (for example "stop").
I came up with an idea of using goroutines, however, I can't type in commands because the input field is changing to output.
Here is my code:
package main
import (
"bufio"
"os"
)
var process bool = true
func commandHandler() {
reader := bufio.NewReader(os.Stdin)
for process {
text, _ := reader.ReadString('\n')
if text == "stop\r\n" {
process = false
}
}
}
func task() {
var i int64 = 0
for ; i < 10000000000 || process; i++ {
if i%30000000 == 0 { // Just to slow down an output for a while
println(i)
}
}
}
func main() {
go task()
commandHandler()
}
And the result that I get. Letters are my input that I`m trying to type in and numbers - the output of the application
Any suggestions on how to make proper input\output in my Go application?
I can't type in commands because the input field is changing to output
You can type in the commands just fine. They'll be echoed to your console as you type them. This will be combined with everything else that is being output to your console, which can be confusing to the user - but not to the computer.
Your program works just fine, assuming this actually matches on your OS:
if text == "stop\r\n" {
On my OS there's no \r. A more portable method would be to use strings.TrimSpace to remove all the whitespace.
import (
...
"strings"
)
...
...
if strings.TrimSpace(text) == "stop" {
With this change, the code works for me. As you said, the output and input is interpolated onto the screen, but you can still type stop and end the program.
Any suggestions on how to make proper input\output in my Go application?
Almost no real world terminal programs are interactive. Instead command line arguments and environment variables provide their configurationat invocation time. Shell redirection is typically used to retain (in a file) or paginate (eg |less) any long output of a program.
You'll see a lot of academic programming using interactive terminal models where the program prompts the user and collects data, but in the real world this is very rare and is generally an ill advised complication. Standard input is typically used to provide data input for computation, rather than user commands (for example, data to be manipulated or filtered).
As #tinkerer suggests, signals can already be used to terminate your program (details are OS specific). So there's really no need to worry about how a terminal application would handle the visual representation of standard input and output being interpolated just to terminate the program. In a Posix environment there are a number of other signals, some of which are entirely user oriented and can be used for arbitrary purposes.
Once more complicated user input is required at runtime, the program typically listens on a socket for commands. For this kind of program, web interfaces serving HTTP have become increasingly common for the simplicity and accessibility.

How does crypto/rand generate a secure random number?

I started to geek out and I wanted to see how https://golang.org/src/crypto/rand/rand_unix.go works on the inside.
I wanted to see when it generates rands from dev/random (more secure) and when it generates from dev/urandom(less security)
It looks like if rand_batched.go is initialized (this initializes altGetRandom) and GOOS is not plan9 (then r.name = urandomDevice it will return the length of the random array and not the content (which is surprising, why the length?)
see line 57:
if altGetRandom != nil && r.name == urandomDevice && altGetRandom(b) {
return len(b), nil
}
else it will simply return the content of the array which will be based on dev/random only if GOOS=plan9.
So why should it ever return len(b)?
Also it looks to me that most of the time it will use dev/urandom which is suboptimal... am I wrong (guess so because of docs, but help me understand)?
altGetRandom is used on systems where there is a system call to get random bytes, rather than depending on the existence of /dev/urandom. This is sometimes useful in special environments (a chroot where there is no /dev, Docker-ish systems with weird/wrong /dev, FreeBSD jails with an incorrect /dev setup, etc.), and also is a bit faster than opening the file (as it does not go through quite as many system call layers), though in general one should just use the file.
The call in question is in an io.Reader-style function, whose job is to return the length of the block of bytes read, and any error. When using the system call, the OS fills in—or is assumed to fill in—the array b completely, so len(b) is the correct result.

Golang errors and documentation

Unfortunately golang error documentation in the standard library is next to non-existent. e.g. just opening a file, the return values for the error are not documented except that you can print a string. But this is not always the right way to handle it.
Is there a way to determine what the real error code might be through trial and error rather than just printing out the text? It seems silly to match the whole text for the specific error.
e.g. given I want to ultimately achieve something like this (assuming it's right)
if fd, err := io.Open("filename"); err != nil {
if err != io.ErrFileNotFound {
log.Fatalf("Error opening file: %s", err)
}
}
As far as I can tell anything that implements the error interface will be able to be used as an error. But determining what the error is is what I'm struggling with. The error may be a struct that has other fields in it like a number field to tell me what type of error it is aside from the text itself.
But how would I know what other data the error contains short of looking through many source files and sometimes tens of function calls.
Does this make sense?
As a more practical example. I am using a yaml library to load a config file.
If the config file doesn't exist I want to carry on (it'll use defaults). But if there is a permissions error I want the error to be treated as fatal. The problem is, it's not entirely clear what the error will look like ahead of time.
Use os.IsNotExist to check for file not found errors:
f, err := os.Open("filename")
if os.IsNotExist(err) {
// handle missing file
} else if err != nil {
// handle other errors
}
The functions os.IsExist, os.IsPermission and is.Timeout check for other common types of errors.
The os, io and other packages declare variables for specific errors.
Always check godoc if you are not cleared about a library.
.below is the godoc io URL and read more
https://godoc.org/io

Trick to quickly find file & line number throwing an error in Go?

In my journey with go discovered that there are no stacktraces. so whenever something breaks, all we get an simple string error message without any information where is this is coming from. This is in stark contrast with other languages where I am used to seing detailed stacktraces
For example, below is the error message from apex
$ cat event.json | apex invoke --logs webhook
⨯ error parsing response: json: cannot unmarshal array into Go value of type map[string]interface {}
here its telling me that unmarshal to a map ins't working because event.json is an array. We have unmarshal to interface{} to support both arrays & maps.However, it doesn't tell me which file/line is causing this error.
Questions:
What is way to quickly find which file/line this error coming from?
In General, Are there tips/tricks which gophers use to get to the source of problem quickly from this string error message?
is this how stack traces are for most go projects or there are any best practices that should be followed?
What is way to quickly find which file/line this error coming from?
There are no default stacks printed unless it's an unrecovered panic.
In General, Are there tips/tricks which gophers use to get to the source of problem quickly from this string error message? is this how stack traces are for most go projects or there are any best practices that should be followed?
In General, you need to check error returns from most of the function calls. There are more than one way to do that.
I usually use standard library package log to print out error logs with file and line numbers for easy debugging in simple programs. For example:
package main
import "log"
import "errors"
func init() { log.SetFlags(log.Lshortfile | log.LstdFlags) }
func callFunc() error {
return errors.New("error")
}
func main() {
if err := callFunc(); err != nil {
log.Println(err)
}
}
http://play.golang.org/p/0iytNw7eZ7
output:
2009/11/10 23:00:00 main.go:14: error
Also, there are functions for you to print or retrieve current stacks in standard library runtime/debug, e.g. https://golang.org/pkg/runtime/debug/#PrintStack
There are many community efforts on bringing error handling easier, you can search error in GoDoc: https://godoc.org/?q=error
Your attempted solution: Finding the piece of code that produces the error to fix the code.
Your actual problem: The content of event.json.
This is called the X-Y-Problem
Invoke expects a json object, you are passing a json array. Fix that and your problem is gone!
$ echo -n '{ "value": "Tobi the ferret" }' | apex invoke uppercase
Relevant part of the documentation: Invoking Functions
And that's the piece of code that produces the error: Github
And yes, Go does have stack traces! Read Dave Cheneys blog post on errors and exceptions.
Go does produce stack traces when a panic happens, crashing the program. This will happen if the code calls panic() directly, typically in cases like:
if err != nil {
panic("it broke")
}
or, when a runtime error happens:
a := []int{1, 2, 3}
b := a[12] // index out of range
Here's a minimal example:
package main
func main() {
panic("wtf?!")
}
Output:
panic: wtf?!
goroutine 1 [running]:
panic(0x94e60, 0x1030a040)
/usr/local/go/src/runtime/panic.go:464 +0x700
main.main()
/tmp/sandbox366642315/main.go:4 +0x80
Note the main.go:4 indicating the filename and line number.
In your example, the program did not panic, instead opting to call (I'm guessing) os.Exit(1) or log.Fatal("error message") (which calls os.Exit(1)). Or, the panic was simply recovered from in the calling function. Unfortunately, there's nothing you can do about this if you aren't the author of the code.
I would recommend reading Defer, Panic, and Recover on the Golang blog for more about this.
Setting log.SetFlags(log.LstdFlags | log.Lshortfile) in main() should do it.
For example, log.Printf("Deadline!") would print:
03/11/2020 23:59:59 liberty_test.go:42: Deadline!

Is it possible to use gofmt on templates that are designed to be used with go generate?

I am using go:generate to handle automatically generating some database models and I was hoping to run my go template through gofmt, but it chokes with all the extra {{ ... }} dynamic sections.
Am I missing something obvious? I was hoping that this was a use case the gofmt people had addressed, given both gofmt and go generate are prominent parts of the go toolchain.
Obviously, it works to just run go fmt after go generate but it just feels dirty to have poorly formatted templates that are 99% go code sitting around.
Most generation tools execute the template to a *bytes.Buffer, format the buffer bytes using format.Source and write the result to the output file.
Given template t and output writer w, the code looks something like this:
var buf bytes.Buffer
if err := t.Execute(&buf, data); err != nil {
// handle error
}
p, err := format.Source(buf.Bytes())
if err != nil {
// handle error
}
w.Write(p)
Gofmting the template does not ensure that the output will be gofmted. Given how easy it is to gofmt the output using the go/format package, there's little value in creating a tool to gofmt templates.

Resources