1 回答

TA貢獻(xiàn)1942條經(jīng)驗 獲得超3個贊
在您的進(jìn)程中,您將os.Stdout文件描述符直接傳遞給您調(diào)用以運行子進(jìn)程的命令。這意味著子進(jìn)程的 STDOUT 管道將直接連接到您的 Go 程序的標(biāo)準(zhǔn)輸出,并且如果兩個子進(jìn)程同時寫入,則可能會交錯。
解決這個問題的最簡單方法需要您在 Go 程序中緩沖來自子進(jìn)程的 STDOUT 管道的輸出,這樣您就可以攔截輸出并在打印時進(jìn)行控制。
Cmd包中的類型提供os/exec了一個函數(shù)調(diào)用Output(),它將調(diào)用子進(jìn)程并以字節(jié)片的形式返回 STDOUT 的內(nèi)容。您的代碼可以輕松調(diào)整以實現(xiàn)此模式并處理結(jié)果,例如:
func whois() {
cmd := exec.Command("whois", "google.co")
out, err := cmd.Output()
if err != nil {
log.Fatal(err)
}
fmt.Println(out)
wg.Done()
}
交織輸出
如果您使用fmt包中的函數(shù)來打印輸出,則不能保證并發(fā)調(diào)用fmt.Println不會交錯。
為防止交錯,您可以選擇序列化對 STDOUT 的訪問,或使用可安全并發(fā)使用的記錄器(例如包log)。下面是一個在 Go 進(jìn)程中序列化訪問 STDOUT 的例子:
package main
import (
"fmt"
"log"
"os/exec"
"sync"
)
var url string
func nikto(outChan chan<- []byte) {
cmd := exec.Command("nikto", "-h", url)
bs, err := cmd.Output()
if err != nil {
log.Fatal(err)
}
outChan <- bs
}
func whois(outChan chan<- []byte) {
cmd := exec.Command("whois", "google.com")
bs, err := cmd.Output()
if err != nil {
log.Fatal(err)
}
outChan <- bs
}
func main() {
outChan := make(chan []byte)
fmt.Printf("Please input URL")
fmt.Scanln(&url)
go nikto(outChan)
go whois(outChan)
for i := 0; i < 2; i++ {
bs := <-outChan
fmt.Println(string(bs))
}
}
- 1 回答
- 0 關(guān)注
- 295 瀏覽
添加回答
舉報