Question

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.

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top