2014-03-27 69 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'。 –