>백엔드 개발 >Golang >Go에서 명령을 실행하고 상위 프로세스에서 분리하는 방법은 무엇입니까?

Go에서 명령을 실행하고 상위 프로세스에서 분리하는 방법은 무엇입니까?

Patricia Arquette
Patricia Arquette원래의
2024-10-29 04:35:021067검색

How to Execute a Command in Go and Detach It from the Parent Process?

Go에서 명령을 실행하고 프로세스에서 분리

Go에서는 분리된 방식으로 명령을 실행하여 실행할 수 있습니다. 프로그램과 독립적으로. 이를 달성하는 방법은 다음과 같습니다.

코드:

<code class="go">package main

import (
    "fmt"
    "log"
    "os"
    "os/exec"
    "strconv"
    "syscall"
)

func main() {
    // Define the command and its arguments
    cmd := exec.Command("sleep", "120")

    // Set up the pipes for stdout and stderr
    stdoutPipe, err := cmd.StdoutPipe()
    if err != nil {
        log.Fatal(err)
    }
    stderrPipe, err := cmd.StderrPipe()
    if err != nil {
        log.Fatal(err)
    }

    // Start the command
    if err := cmd.Start(); err != nil {
        log.Fatal(err)
    }

    // Get the process ID (PID) of the child process
    pid := cmd.Process.Pid

    // Print the PID
    fmt.Printf("PID: %d\n", pid)

    // Read from the stdout and stderr pipes and log the output
    go func() {
        for {
            buf := make([]byte, 1024)
            n, err := stdoutPipe.Read(buf)
            if err != nil {
                log.Fatal(err)
            }
            fmt.Printf("stdout: %s", string(buf[:n]))
        }
    }()
    go func() {
        for {
            buf := make([]byte, 1024)
            n, err := stderrPipe.Read(buf)
            if err != nil {
                log.Fatal(err)
            }
            fmt.Printf("stderr: %s", string(buf[:n]))
        }
    }()

    // Wait for the command to finish
    if err := cmd.Wait(); err != nil {
        if exitErr := cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus(); exitErr != 0 {
            log.Fatal(fmt.Sprintf("Error #48692663: Command exited with code %d", exitErr))
        } else {
            log.Printf("Command exited with exit code 0")
        }
    }

    // Optionally, keep the child process alive even after the parent process exits
    // This can be achieved by setting `cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}` before starting the command.

    // Example of sending a signal to the detached process
    if err := syscall.Kill(pid, os.Interrupt); err != nil {
        log.Fatalf("Error sending signal to process: %d: %s", pid, err)
    } else {
        fmt.Printf("Received ^C and forwarded to process %d\n", pid)
    }

    // Optionally, use `syscall.Reap()` to clean up any child processes that are terminated but not yet waited for.
}</code>

이 코드는 명령을 분리된 방식으로 실행하여 명령이 독립적으로 계속 실행되도록 하는 방법을 보여줍니다. 부모 프로세스. 이는 stdout 및 stderr 캡처, 프로세스 ID 획득, 선택적으로 하위 프로세스에 신호 전송 등의 기능을 제공합니다.

주요 고려 사항:

  • 커널이 여전히 프로세스에 대한 참조를 보유하고 있으므로 프로세스를 분리해도 상위 프로세스 종료 시 고아가 되는 것을 방지할 수는 없습니다.
  • SysProcAttr.Setpgid를 사용하면 하위 프로세스를 독립적으로 활성 상태로 유지할 수 있지만 추가 작업이 필요할 수 있습니다. 특정 경우에 처리됩니다.
  • 프로세스가 종료 코드를 반환하고 잠재적인 오류를 처리할 수 있도록 하려면 Wait()를 사용해야 합니다.
  • syscall.Reap()을 사용하여 정리하세요. 리소스 누출을 방지하기 위한 좀비 프로세스.

위 내용은 Go에서 명령을 실행하고 상위 프로세스에서 분리하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.