2 回答

TA貢獻1893條經驗 獲得超10個贊
該程序會按照您的要求復制內容。您也可以嘗試評論部分。這些評論是不言自明的,我希望它能解釋您的疑問。
package main
import (
"io"
"log"
"os"
"os/exec"
)
func main() {
// Execute cat command w/ arguments
// cmd := exec.Command("cat", "hello.txt")
// Execute cat command w/o arguments
cmd := exec.Command("cat")
// Attach STDOUT stream
stdout, err := cmd.StdoutPipe()
if err != nil {
log.Println(err)
}
// Attach STDIN stream
stdin, err := cmd.StdinPipe()
if err != nil {
log.Println(err)
}
// Attach STDERR stream
stderr, err := cmd.StderrPipe()
if err != nil {
log.Println(err)
}
// Spawn go-routine to copy os's stdin to command's stdin
go io.Copy(stdin, os.Stdin)
// Spawn go-routine to copy command's stdout to os's stdout
go io.Copy(os.Stdout, stdout)
// Spawn go-routine to copy command's stderr to os's stderr
go io.Copy(os.Stderr, stderr)
// Run() under the hood calls Start() and Wait()
cmd.Run()
// Note: The PIPES above will be closed automatically after Wait sees the command exit.
// A caller need only call Close to force the pipe to close sooner.
log.Println("Command complete")
}

TA貢獻1845條經驗 獲得超8個贊
您正在用其他 Go 類型替換進程文件描述符(通常為 )*os.File
。為了讓 stdin 像流一樣工作,os/exec
包需要啟動一個 goroutine 在io.Reader
進程之間復制數據。這在os/exec
包中記錄:
// Otherwise, during the execution of the command a separate
// goroutine reads from Stdin and delivers that data to the command
// over a pipe. In this case, Wait does not complete until the goroutine
// stops copying, either because it has reached the end of Stdin
// (EOF or a read error) or because writing to the pipe returned an error.
如果您查看程序的堆棧跟蹤,您會發現它正在等待 io goroutine 在以下位置完成Wait():
goroutine 1 [chan receive]:
os/exec.(*Cmd).Wait(0xc000076000, 0x0, 0x0)
? ? /usr/local/go/src/os/exec/exec.go:510 +0x125
main.main()
因為您現在可以控制數據流,所以您可以根據需要關閉它。如果這里不需要 Stdin,那么根本就不要分配它。如果要使用它,那么您必須Close()
將其Wait()
歸還。
另一種選擇是確保您使用的是*os.File
,最簡單的方法是使用StdinPipe
,StdoutPipe
和StderrPipe
方法,后者又使用os.Pipe()
.?這種方式確保進程只處理*os.File
,而不處理其他 Go 類型。
- 2 回答
- 0 關注
- 194 瀏覽
添加回答
舉報