如何在Go中使用系统的命令外壳? [重复]

This question already has an answer here:

So I would like to create a command shell in Go. My goal is to use its capabilities in portable system tools I'm thinking about writing. I think a great starting point would be something that can demonstrate the basics of running system commands and allowing the user to interact with the system shell.

</div>

I have such a solution! I actually have it posted in a Gist at gist.github.com/lee8oi/a8a90f559fe48355f800

Its a nice little demonstration that uses Go's os/exec package to directly pipe input/output/error to the command instance. When "bash" runs you'll be sitting at a very simple prompt. You can interact with it much like you would with bash (but still pretty simplified). When you run a regular command the output will be displayed then the command will exit (like with "ping"). I think this would make a great starting point for tinkering with ways to interact with the system shell in Go.

package main

import (
    "bufio"
    "fmt"
    "io"
    "log"
    "os"
    "os/exec"
    "sync"
)

func getPipes(c *exec.Cmd) (inp io.Writer, outp, errp io.Reader) {
    var err error
    if inp, err = c.StdinPipe(); err != nil {
        log.Fatal(err)
    }
    if outp, err = c.StdoutPipe(); err != nil {
        log.Fatal(err)
    }
    if errp, err = c.StderrPipe(); err != nil {
        log.Fatal(err)
    }
    return
}

func pipe(wg *sync.WaitGroup, inp io.Reader, outp io.Writer) {
    if wg != nil {
        defer wg.Done()
    }
    r := bufio.NewReader(inp)
    for {
        c, err := r.ReadByte()
        if err != nil {
            return
        }
        fmt.Fprintf(outp, "%s", string(c))
    }
}

func Command(args ...string) {
    var cmd *exec.Cmd
    var wg sync.WaitGroup
    if len(args) > 1 {
        cmd = exec.Command(args[0], args[1:]...)
    } else {
        cmd = exec.Command(args[0])
    }
    inp, outp, errp := getPipes(cmd)
    wg.Add(1)
    go pipe(&wg, errp, os.Stderr)
    wg.Add(1)
    go pipe(&wg, outp, os.Stdout)
    go pipe(nil, os.Stdin, inp)
    if err := cmd.Start(); err != nil {
        log.Fatal("start ", err)
    }
    wg.Wait()
}

func main() {
    Command("bash")
    Command("date")
    Command("echo", "some text")
    Command("ping", "-c 3", "www.google.com")
}