2016-09-30 13 views
1

(참고) Go Inter-Process Communication은 System V IPC에 관한 질문입니다. (끝 참고)이동 : 다른 프로세스와의 양방향 통신?

os/exec을 사용하면 대화식으로 다른 프로세스와 통신 할 수 있습니까? 프로세스의 stdin과 stdout에 대해 fd를 얻고 그 fds를 사용하여 프로세스에 쓰고 읽고 싶습니다.

내가 발견 한 대부분의 예제는 다른 프로세스를 실행 한 다음 출력 결과를 저지르는 것과 관련이 있습니다.

여기 내가 찾는 것과 동일한 파이썬이 있습니다.

p = subprocess.Popen("cmd", stdin=subprocess.PIPE, stdout=subprocess.PIPE) 
(child_stdin, child_stdout) = (p.stdin, p.stdout) 

은 실질적인 예로써, DC에 파이프 라인을 개방 12 34 +p를 전송하고 라인 46 수용 고려한다.

(갱신)

func main() { 
    cmd := exec.Command("dc") 
    stdin, err := cmd.StdinPipe() 
    must(err) 
    stdout, err := cmd.StdoutPipe() 
    must(err) 

    err = cmd.Start() 
    must(err) 

    fmt.Fprintln(stdin, "2 2 +p") 

    line := []byte{} 
    n, err := stdout.Read(line) 

    fmt.Printf("%d :%s:\n", n, line) 
} 

내가 dc 받고 예상대로 응답되는 것을 strace를에 의해 참조 :

[pid 8089] write(4, "12 23 +p\n", 9 <unfinished ...> 
... 
[pid 8095] <... read resumed> "12 23 +p\n", 4096) = 9 
... 
[pid 8095] write(1, "35\n", 3 <unfinished ...> 

하지만 난에 다시 결과를 얻는 것 같지 않습니다 내 호출 프로그램 :

0 :: 

(업데이트)

허용 된 대답에 따라, 내 문제는 응답을받을 문자열을 할당하지 않았습니다. line := make([]byte, 100)로 변경하면 모든 것이 수정되었습니다.

+0

@MarioAlexandroSantini, 중복되지 않습니다. 나는 shmget과 같은 system-V IPC를 찾고 있지 않다. –

+0

길이가 0 인 슬라이스로 읽으려고하므로 어떤 데이터도 읽을 수 없습니다. _into_ (내 예에서는'out'을보십시오)를 읽을 무언가가있을 필요가 있습니다. – JimB

+0

완벽하게 작동합니다. 통찰력에 감사드립니다! –

답변

3

exec.Cmd에는 사용자가 지정할 수있는 stdin, std 및 stderr 프로세스 필드가 있습니다. 당신이 그 중 하나에 연결에 미리 만들어진 파이프를 원하는 경우

// Stdin specifies the process's standard input. 
    // If Stdin is nil, the process reads from the null device (os.DevNull). 
    // If Stdin is an *os.File, the process's standard input is connected 
    // directly to that file. 
    // Otherwise, during the execution of the command a separate 
    // goroutine reads from Stdin and delivers that data to the command 
    // over a pipe. In this case, Wait does not complete until the goroutine 
    // stops copying, either because it has reached the end of Stdin 
    // (EOF or a read error) or because writing to the pipe returned an error. 
    Stdin io.Reader 

    // Stdout and Stderr specify the process's standard output and error. 
    // 
    // If either is nil, Run connects the corresponding file descriptor 
    // to the null device (os.DevNull). 
    // 
    // If Stdout and Stderr are the same writer, at most one 
    // goroutine at a time will call Write. 
    Stdout io.Writer 
    Stderr io.Writer 

, 당신은 dc 프로그램 (체크 산세 오류)를 사용하여 *Pipe() 방법

func (c *Cmd) StderrPipe() (io.ReadCloser, error) 
func (c *Cmd) StdinPipe() (io.WriteCloser, error) 
func (c *Cmd) StdoutPipe() (io.ReadCloser, error) 

에게 기본 예제를 사용할 수 있습니다

cmd := exec.Command("dc") 
stdin, _ := cmd.StdinPipe() 
stdout, _ := cmd.StdoutPipe() 
cmd.Start() 

stdin.Write([]byte("12 34 +p\n")) 

out := make([]byte, 1024) 
n, _ := stdout.Read(out) 

fmt.Println("OUTPUT:", string(out[:n])) 

// prints "OUTPUT: 46"