2 回答

TA貢獻1836條經驗 獲得超4個贊
該命令將版權聲明寫入標準輸出。為避免將版權聲明與輸出文件混在一起,請使用 /dev/stdout 以外的文件作為輸出文件。
下面的函數使用Cmd.ExtraFiles將管道連接到子進程中的 fd 3。該函數將數據從管道復制到字節緩沖區,并將這些字節返回給調用者。
func otherOne(stdin []byte) ([]byte, error) {
r, w, err := os.Pipe()
if err != nil {
return nil, err
}
defer r.Close()
defer w.Close()
cmd := exec.Command("./my_bin", "/dev/stdin", "/dev/fd/3")
cmd.Stdin = bytes.NewReader(stdin)
cmd.ExtraFiles = []*os.File{w} // The first file is fd 3.
if err := cmd.Start(); err != nil {
return nil, err
}
w.Close()
var outbuf bytes.Buffer
if _, err := io.Copy(&outbuf, r); err != nil {
return nil, err
}
if err := cmd.Wait(); err != nil {
return nil, err
}
return outbuf.Bytes(), nil
}

TA貢獻2051條經驗 獲得超10個贊
幾個月后,我想出了另一種方法來解決這個問題。基本思想與Cerise類似,即/dev/fd/3用于重定向輸出文件。之后,我們分別重定向/dev/fd/3到/dev/stdout, verbose log 到/dev/stderr by 3>&1, 1>&2。添加了一個額外gen.sh的。這是解決方案:
#gen.sh
./mybin /dev/stdin /dev/fd/3 3>&1 1>&2
// gen.go
func gen(stdin []byte) ([]byte, error) {
inBuf := bytes.NewBuffer(stdin)
outBuf := bytes.NewBuffer(nil)
cmd := exec.Command("./gen.sh")
cmd.Stdin = inBuf
cmd.Stdout = outBuf
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
return nil, err
}
return outBuf.Bytes(), nil
}
- 2 回答
- 0 關注
- 149 瀏覽
添加回答
舉報