lets say I have this code:
package main
import (
"io/ioutil"
"fmt"
)
func check(err error) {
if err != nil {
panic(err)
}
}
func main() {
file, err := ioutil.ReadFile("test.txt")
check(err)
fmt.Print(string(file))
}
when running it with go run I want it to be written in a cleared bash window. Is it possible to do so without using any additional open-source repositories?
Thanks in advance.
If clearing the terminal is truly part of your program's responsibility then check out the answers in this question How can I clear the terminal screen in Go?
However if you're just wanting to clear the screen as part of your development process then I would keep it simple and do something like this
clear && go run *.go
Related
package main
import (
"fmt"
"time"
evtx "github.com/0xrawsec/golang-evtx/evtx"
)
func main() {
fd, err := evtx.Open("D:\\ForwardedEvents\\Logs\\ForwardedEvents.evtx")
if err != nil {
fmt.Println(err)
}
stopchan := make(chan bool)
mychan := fd.MonitorEvents(stopchan, time.Duration(100))
x := <- mychan
fmt.Println(x)
}
The code I wrote; Windows Event Viewer Dan gets logs and outputs it, but when I run the code it says "File is flagged as a dirty." I am getting the error. How can I fix it?
The library you are using returns the error if the file you are opening is flagged as dirty (it has nothing to do with your IDE). You can choose to ignore the error if you want (or use the OpenDirty function that attempts to repair the file if its dirty but this will not work if something else has it open).
Why is this error arising? Probably because the file was not closed properly (or something is still writing to it). The Microsoft docs say:
The ELF_LOGFILE_HEADER_DIRTY flag can be used by the event-logging service to detect if the event log was not properly closed.
I am trying to create a shell in Go. I currently have this code that reads the os.Stdin and prints it out.
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
buf := bufio.NewReader(os.Stdin)
for {
fmt.Print("> ")
bytes, err := buf.ReadBytes('\n')
if err != nil {
panic(err)
}
fmt.Println(strings.TrimSuffix(string(bytes), "\n"))
}
}
However, while you are typing out your commands, I found that you can not use Command + Backspace to delete a full word like you can usually do in a shell. I found this issue to be pretty annoying and after looking at other similar questions on StackOverflow I saw that some people mentioned that the terminal needs to be in raw mode.
I have tried using termbox-go, but I was not able to get it working. If anyone could point me in the right direction it would be greatly appreciated.
Thanks.
I need to read golang code from the play.golang.org link and save to a .go file. I'm wondering if there is any public API support for play.golang.org. I googled but no hints. Has anyone attempted anything similar?
To get the text of a shared playground program, append ".go" to the URL. For example, you can get the text of the program at https://play.golang.org/p/HmnNoBf0p1z with https://play.golang.org/p/HmnNoBf0p1z.go.
You can upload a program by posting the program text to https://play.golang.org/share. The response is the ID of the shared program. This program uploads stdin to the playground and prints the ID of the uploaded program to stdout:
package main
import (
"io"
"log"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("POST", "https://play.golang.org/share", os.Stdin)
if err != nil {
log.Fatal(err)
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
io.Copy(os.Stdout, resp.Body)
}
Assuming the above program is in upload.go, the following shell script prints HmnNoBf0p1z.
go run upload.go << EOF
package main
import (
"fmt"
)
func main() {
fmt.Println("Hello, playground")
}
EOF
If you want to download the program as a file using a browser, then add the query ?download=true to the .go URL. Example: https://play.golang.org/p/HmnNoBf0p1z.go?download=true
There are two ways that I know one of which is described by #ThunderCat. Another simple solution is go to the URL https://play.golang.org/p/HmnNoBf0p1z and Press Ctrl+save on the page it will be downloaded as a .go file.
I started learning and playing around with Go to see what it is like to make some more complex console/cli type tools instead of using shells or Python. I want to execute commands and display the output. I figured out how to print the output like this:
out, err := exec.Command("pwd").Output()
print(string(out))
Is there a way to execute the commands and have it default to stdout like a shell script, or do I need to make a helper function for this?
Update: After getting IntelliJ and the Go plugin, I poked around in the Go source and agree there is currently no way to do with without a helper method.
It is not possible to reuse a Cmd object as per this comment in the exec.go source code:
// A Cmd cannot be reused after calling its Run, Output or CombinedOutput
// methods.
I did incorporate the stdout option into my own helper, including other options like shell integration. I will try turn that into open source if I can make it useful. An interesting first day of Go.
The solution
Actually, it is pretty easy. You can set the stdout of the command to os.Stdout and Bob's your uncle:
package main
import (
"os"
"os/exec"
)
func main() {
cmd := exec.Command("pwd")
cmd.Stdout = os.Stdout
err := cmd.Run()
if err != nil {
panic(err)
}
}
What's happening here?
By default, the output of a command is stored in a bytes.Buffer if cmd.Stdout is not set to another io.Writer. The call of cmd.Output() then runs the command and saves the output to said buffer.
Since os.Stdout implements io.Writer interface, we simply set cmd.Stdout to be os.Stdout. Now when .Run() is called, the output of the command gets written to the io.Writer defined in cmd.Stdout, which happens to be os.Stdout and the output gets written in the shell.
EDIT: As per comment, if all commands should write to os.Stdout, there of course is no way to prevent some helper. I'd do it like this:
package main
import (
"os"
"os/exec"
)
func CmdToStdout( c string ) (err error){
cmd := exec.Command(c)
cmd.Stdout = os.Stdout
err = cmd.Run()
return
}
func main() {
err := CmdToStdout("pwd")
if err != nil {
panic(err)
}
}
You have to create a helper if you need this often (and 5 lines looks too much). Based on the documentation this is a recommended way:
package main
import (
"fmt"
"log"
"os/exec"
)
func main() {
out, err := exec.Command("date").Output()
if err != nil {
log.Fatal(err)
}
fmt.Printf("The date is %s\n", out)
}
I have a program that reads a filename from the console and executes go run filename.go.
// main.go
package main
import (
"bufio"
"fmt"
"log"
"os"
"os/exec"
)
func main() {
console := bufio.NewReader(os.Stdin)
fmt.Print("Enter a filename: ")
input, err := console.ReadString('\n')
if err != nil {
log.Fatalln(err)
}
input = input[:len(input)-1]
gorun := exec.Command("go", "run", input)
result, err := gorun.Output()
if err != nil {
log.Println(err)
}
fmt.Println("---", input, "Result ---")
fmt.Println(string(result))
}
In the same directory, I have another file like this.
// hello.go
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
When I input "hello.go" in the console, that file is run, and its output gets returned to the parent Go process. However, I have another program like this.
// count.go
package main
import (
"fmt"
"time"
)
func main() {
i := 0
for {
time.Sleep(time.Second)
i++
fmt.Println(i)
}
}
Except, because this program never returns, my parent process is left hanging forever. Is there a way to communicate with different Go processes? I'm thinking something like channels for goroutines, but for processes. I need to be able to receive live stdout from the child process.
The problem I'm trying to solve is dynamically executing Go programs from a directory. Go files will be added, removed, and modified daily. I'm kind of trying to make something like Go Playgrounds. The main process is a webserver serving webpages, so I can't shut it down all the time to modify code.
Don't use go run, you need to do what go run is doing yourself to have the go program be a direct child of your server process.
Using go build -o path_to/binary source_file.go will give you more control. Then you can can directly execute and communicate with the resulting binary.