2017-05-30 43 views
-1

我有一個虛擬程序,我在用stdin搞亂。我希望能夠以編程方式寫入標準輸入以及從中讀取。出於某種原因,我無法閱讀我寫給stdin的信息。它會簡單地阻止,直到它通過終端/主機接收來自用戶的輸入爲什麼我不能讀取我寫給標準輸入的字符串

func main() { 
    writer := bufio.NewWriter(os.Stdin) 
    reader := bufio.NewReader(os.Stdin) 

    fmt.Println("Writing to stdin") 
    _, err := writer.WriteString("Hello, world\n") 
    writer.Flush() 
    checkErr(err) 
    fmt.Println("Reading from it") 
    line, err := reader.ReadString('\n') 
    checkErr(err) 
    fmt.Println("Line from stdin: ", line) 

} 

func checkErr(err error) { 
    if err!= nil { 
     fmt.Println("Error: ", err.Error()) 
    } 
} 

輸出如下:

Writing to stdin 
Reading from it //blocks here until I input some string from console and hit <Enter> 
+0

嘗試使用io.Copy(dst,src)https://golang.org/pkg/io/#Copy – peeyushsrj

+4

當您從終端執行您的go程序時,stdin是一個tty,因此寫入它只是寫入到TTY。 – JimB

+0

請參閱 https://stackoverflow.com/q/11127970 和 https://stackoverflow.com/q/1441251 – Krom

回答

1

根據操作系統和程序如何啓動,stdin可許多不同的東西,並非所有的東西都可以寫出來。所以一般不支持寫入stdin

例如:如果你在一個終端上在linux上啓動你的程序,stdin,stdoutstderr都是相同的端點,那就是你的終端。寫入任何這些將在屏幕上產生輸出,當您從stdin讀取時,您將無法送回。 (在哪裏你只能看到東西,終端會通過它的從屬設備傳遞給你)

如果你想回讀,你寫的是stdin,你可以創建一個簡單的包裝器,它啓動你的程序,從程序返回到它的輸入得到,像這樣

package main 

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

func main() { 
     cmd := flag.String("cmd", "none", "command to run and loop output back to input") 
     flag.Parse() 
     process := exec.Command(*cmd) 
     input, err := process.StdinPipe() 
     if err != nil { 
       log.Fatalln(err) 
     } 
     output, err := process.StdoutPipe() 
     if err != nil { 
       log.Fatalln(err) 
     } 
     errors, err := process.StderrPipe() 
     if err != nil { 
       log.Fatalln(err) 
     } 
     err = process.Start() 
     if err != nil { 
       log.Fatalln(err) 
     } 
     _, err = io.Copy(input, output) 
     if err != nil { 
       log.Println(err) 
     } 
     err = input.Close() 
     if err != nil { 
       log.Fatalln(err) 
     } 
     errorsScanner := bufio.NewScanner(errors) 
     for errorsScanner.Scan() { 
       fmt.Println(errorsScanner.Text()) 
     } 
     err = process.Wait() 
     if err != nil { 
       log.Fatalln(err) 
     } 
     fmt.Println("all done") 
} 

我打電話給該工具outinloop,並要求它像outinloop -cmd="testprog"

一個適宜的測試程序將

package main 

import (
     "bufio" 
     "fmt" 
     "log" 
     "os" 
) 

func main() { 
     fmt.Println("vim-go") 
     err := os.Stdout.Close() 
     if err != nil { 
       log.Fatalln(err) 
     } 
     in := bufio.NewScanner(os.Stdin) 
     if !in.Scan() { 
       fmt.Fprintf(os.Stderr, "no input?\n") 
       os.Exit(1) 
     } 
     if in.Text() == "vim-go" { 
       fmt.Fprint(os.Stderr, "all is well\n") 
       return 
     } 
     fmt.Fprintf(os.Stderr, "wrong input: %s\n", in.Text()) 
     os.Exit(1) 
} 
相關問題