go-cmd / cmd

Non-blocking external commands in Go with streaming output
MIT License
918 stars 128 forks source link

unable to use with binary stdout #86

Open majelbstoat opened 2 years ago

majelbstoat commented 2 years ago

I'm using exec.Cmd() to run graphics magick to convert an image, reading from stdin and writing to stdout.

    stdout := bytes.Buffer{}
    stderr := bytes.Buffer{}
    gm := exec.Command("gm", "convert", args...)
    gm.Stdin = bytes.NewReader(img.Data)
    gm.Stdout = &stdout
    gm.Stderr = &stderr

    err = gm.Run()
    if err != nil {
        return nil, fmt.Errorf("gm: %s", stderr.String())
    }
    new := stdout.Bytes()

I've been using go-cmd for all my other commands, but for this use case, it doesn't seem possible, because go-cmd treats all its outputs as strings. Is that correct? I'd love to be doing other work while I wait for the conversion to finish.

daniel-nichter commented 2 years ago

Yes, it presumes output is lines of strings. Internally, it does just buffer data, but then calls like https://github.com/go-cmd/cmd/blob/v1.4.0/cmd.go#L334 presume string lines. I'm not sure it's feasible to adapt to binary output because the string line presumption is baked into the design.

majelbstoat commented 2 years ago

Thanks for the clarification. Instead of a replacement, would the addition of a status.StdoutReader which just returned an io.Reader over the internal data, and/or something similar on an OutputStream be feasible, or are there internals that would break if the data was accessed in that way?