[go] Go에서 자식 프로세스의 stdout 파이프 리디렉션

나는 프로그램 (또한 Go)과 같은 서버를 실행하는 프로그램을 Go로 작성하고 있습니다. 이제 부모 프로그램을 시작한 터미널 창에서 자식 프로그램의 표준 출력을 원합니다. 이를 수행하는 한 가지 방법은 cmd.Output()함수를 사용하는 것이지만 프로세스가 종료 된 후에 만 ​​stdout을 인쇄합니다. (이 서버와 같은 프로그램이 오랫동안 실행되고 로그 출력을 읽고 싶기 때문에 문제입니다)

변수 out는 of type io.ReadCloser이고 내 작업을 수행하기 위해 무엇을해야하는지 모르겠으며이 주제에 대한 웹에서 유용한 정보를 찾을 수 없습니다.

func main() {
    cmd := exec.Command("/path/to/my/child/program")
    out, err := cmd.StdoutPipe()
    if err != nil {
        fmt.Println(err)
    }
    err = cmd.Start()
    if err != nil {
        fmt.Println(err)
    }
    //fmt.Println(out)
    cmd.Wait()
} 

코드 설명 : Println컴파일 할 코드를 얻으려면 함수의 주석 처리를 제거하십시오 Println(out io.ReadCloser). 의미있는 함수가 아님을 알고 있습니다.
(출력을 생성합니다 &{3 |0 <nil> 0})이 두 줄은 코드를 컴파일하는 데 필요합니다.



답변

이제 부모 프로그램을 시작한 터미널 창에서 자식 프로그램의 표준 출력을 원합니다.

파이프 나 고 루틴을 엉망으로 만들 필요가 없습니다. 이것은 쉽습니다.

func main() {
    // Replace `ls` (and its arguments) with something more interesting
    cmd := exec.Command("ls", "-l")
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr
    cmd.Run()
}


답변

나는 이것을 수입 하고 교체 한다면 다음 io과 같이 믿는다 os.

//fmt.Println(out)

이것으로 :

go io.Copy(os.Stdout, out)

(문서 참조 에 대한io.Copy를 들어os.Stdout , 당신이 원하는 것을 할 것입니다). (면책 조항 : 테스트되지 않음)

그건 그렇고, 당신은 아마 만에, 표준 출력과 동일한 방법을 사용하여뿐만 아니라 표준 오류를 캡처 할 수 있습니다 cmd.StderrPipeos.Stderr.


답변

루프에서 이것을 필요로하지 않지만 cmd.Wait()다른 명령문 을 차단 하지 않고 명령 출력이 터미널로 에코되도록하려는 사람들을 위해 :

package main

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

func checkError(err error) {
    if err != nil {
        log.Fatalf("Error: %s", err)
    }
}

func main() {
    // Replace `ls` (and its arguments) with something more interesting
    cmd := exec.Command("ls", "-l")

    // Create stdout, stderr streams of type io.Reader
    stdout, err := cmd.StdoutPipe()
    checkError(err)
    stderr, err := cmd.StderrPipe()
    checkError(err)

    // Start command
    err = cmd.Start()
    checkError(err)

    // Don't let main() exit before our command has finished running
    defer cmd.Wait()  // Doesn't block

    // Non-blockingly echo command output to terminal
    go io.Copy(os.Stdout, stdout)
    go io.Copy(os.Stderr, stderr)

    // I love Go's trivial concurrency :-D
    fmt.Printf("Do other stuff here! No need to wait.\n\n")
}


답변