2013-02-09 3 views
0

Golang 프로그램에서 생성 한 후 일부 프로그램과 완전히 통신 할 수 있기를 원합니다.파이프를 사용하여 프로그램 프로세스와 통신하기

package main 

import (
    "fmt" 
    "io" 
    "log" 
    "os/exec" 
    "strings" 
) 

var stdinPipe io.WriteCloser 
var stdoutPipe io.ReadCloser 
var err error 

func main() { 
    cmd := &exec.Cmd{ 
     Path: "/Users/seba/Projects/go/src/bootstrap/in", 
     Args: []string{"program"}, 
    } 

    stdinPipe, err = cmd.StdinPipe() 

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

    stdoutPipe, err = cmd.StdoutPipe() 

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

    err = cmd.Start() 

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

    var stdoutLines []string 
    go stdoutManage(stdoutLines, stdoutController) 

    cmd.Wait() 
} 

// TODO: imporove as in io.Copy 
func stdoutManage(lines []string, manager func(string)) { 
    buf := make([]byte, 32*1024) 

    for { 
     nr, err := stdoutPipe.Read(buf) 

     if nr > 0 { 
      thelines := strings.Split(string(buf), "\n") 
      for _, l := range thelines { 
       manager(l) 
       lines = append(lines, l) 
      } 
     } 

     buf = make([]byte, 32*1024) // clear buf 

     if err != nil { 
      break 
     } 
    } 
} 

그러나이 방법은 어떻게 든 표준 입력 완충 용액에 표준 입력을 사용하지 않는 터미널 출력 및 프로그램을 삭제 프로그램에 문제가 있습니다 : 내가 이미 가지고있는 것은 표준 출력에서 ​​읽을 산란 과정과 마지막 줄에 따라 파이프를 통해 이야기입니다 모두 (그것이 가능한지 모른다).

그래서 질문 : 프로그램과 대화 할 수있는 휴대용 방법이 있습니까? (이것은 골란 솔루션이 아닐 수 있습니다)?

답변

3

이와 같은 문제는 보통 stdin/stdout/stderr이 정확히 무엇인지에 따라 C library which changes its default buffering 모드와 관련이 있습니다.

stdout이 터미널이면 버퍼링이 자동으로 버퍼링 된 줄로 설정되고 그렇지 않으면 버퍼링되도록 설정됩니다.

파이프를 통해 프로그램을 실행할 때 터미널에 연결되어 있지 않으므로 이러한 종류의 사용을 망칠 수있는 버퍼링이 있기 때문에 이는 사용자에게 적합합니다.

수정하려면 터미널 인 것처럼 보이지만 파이프처럼 작동하는 의사 tty를 사용해야합니다. 여기에 실제로 시도하지 않은 the pty interface을 구현하는 라이브러리가 있지만 올바른 일을하는 것처럼 보입니다!

+0

고마워요! 이것은 내 문제를 해결합니다. –

관련 문제