2014-03-27 68 views
5

GO:是否有某種方式與正在等待stdin輸入的子進程(shell腳本/ python腳本)進行通信?Go子進程通信

例如python腳本(子)

import sys 
while True: 
    sys.stdout.write('%s\n'%eval(sys.stdin.readline())) 

在走程序,我想創造這個python腳本的子進程,並提供它的標準輸入,在有需要時,反覆輸入,並採取它的輸出。在Go程序的標準輸出或從文件中讀取/寫入也是可行的。

這大致是什麼,我想,但沒有任何反應 -

c := exec.Command("python", "-u add.py") 
si,_ := c.StdinPipe() 
so,_ := c.StdoutPipe()  
c.Start() 
si.Write([]byte("2+2\n") 
+0

無關:你可以用'輸入'取代的eval(sys.stdin.readline())'()'關於Python 2.或者替換'進口整個循環碼; shell = code.InteractiveConsole(); shell.interact()'或者直接啓動'python -i'進程。 – jfs

+0

這就是爲什麼你不應該忽略錯誤,試試'exec.Command(「python」,「-u」,「add.py」)或者'exec.Command(「python」,「-u」,「 -i「)或exec.Command(」python「,」-i「)'(如果它不使輸出完全緩衝) – jfs

+0

沒有錯誤。仍然無法正常工作 –

回答

3

這裏是您旅途中的代碼的工作版本(Python代碼不變)。

注意:檢查所有錯誤,修復-u標誌,使用bufio來讀取一行,並且Wait等待處理結束。

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

func main() { 
    c := exec.Command("python", "-u", "add.py") 
    si, err := c.StdinPipe() 
    if err != nil { 
     log.Fatal(err) 
    } 

    so, err := c.StdoutPipe() 
    if err != nil { 
     log.Fatal(err) 
    } 
    reader := bufio.NewReader(so) 

    err = c.Start() 
    if err != nil { 
     log.Fatal(err) 
    } 

    // Now do some maths 
    for i := 0; i < 10; i++ { 
     sum := fmt.Sprintf("2+%d\n", i) 
     _, err = si.Write([]byte(sum)) 
     if err != nil { 
      log.Fatal(err) 
     } 
     answer, err := reader.ReadString('\n') 
     if err != nil { 
      log.Fatal(err) 
     } 
     fmt.Printf("Answer to %q is %q\n", sum, answer) 
    } 

    // Close the input and wait for exit 
    si.Close() 
    so.Close() 
    c.Wait() 
} 

將會產生

Answer to "2+0\n" is "2\n" 
Answer to "2+1\n" is "3\n" 
Answer to "2+2\n" is "4\n" 
Answer to "2+3\n" is "5\n" 
Answer to "2+4\n" is "6\n" 
Answer to "2+5\n" is "7\n" 
Answer to "2+6\n" is "8\n" 
Answer to "2+7\n" is "9\n" 
Answer to "2+8\n" is "10\n" 
Answer to "2+9\n" is "11\n" 
+0

非常感謝.... –

+1

如果向循環添加延遲會發生什麼?它是否一次一個或全部一次打印結果?你需要'si.Flush()'還是'si'沒有緩衝? Windows上需要'\ r \ n'嗎? – jfs

+1

@ J.F.Sebastian它可以正常工作,如果你添加一個延遲 - 結果逐一緩慢出現。所有東西都沒有緩衝(上面的'bufio'除外),所以不需要衝洗。 '-u'負責python的結束。不確定'sys.stdin.readline()'是否會在窗口上讀取'\ n'或'\ r \ n',但是go prog會發送並期望'\ n'。 –