使用重定向到文件启动分离命令

ros*_*euz 2 io process go

我试图在一个分离的进程中启动一个命令,以便它可以在 go 程序退出后继续。我需要将命令的输出重定向到一个文件。

我需要的是这样的:

func main() {
    command := exec.Command("/tmp/test.sh", ">", "/tmp/out")

    if err := command.Start(); err != nil {
        fmt.Fprintln(os.Stderr, "Command failed.", err)
        os.Exit(1)
    }

    fmt.Println("Process ID:", command.Process.Pid)
}
Run Code Online (Sandbox Code Playgroud)

显然,这种重定向不起作用。当我在启动长时间运行的命令后立即退出程序时,我无法打开文件并将其绑定到 Stdout。

有没有办法实现这样的重定向?

icz*_*cza 5

您可以启动一个 shell 来执行您的命令/应用程序,并且您可以将其输出重定向到一个文件。即使您的 Go 应用程序退出,shell 也会继续运行并执行您的脚本/应用程序。

例子:

cmd := exec.Command("sh", "-c", "/tmp/test.sh > /tmp/out")
if err := cmd.Start(); err != nil {
    panic(err)
}
fmt.Println("Process ID:", cmd.Process.Pid)
Run Code Online (Sandbox Code Playgroud)

用这个简单的 Go 应用程序测试它(替换/tmp/test.sh为你编译成的可执行二进制文件的名称):

package main
import ("fmt"; "time")
func main() {
    for i := 0; i < 10; i++ {
        fmt.Printf("%d.: %v\n", i, time.Now())
        time.Sleep(time.Second)
    }
}
Run Code Online (Sandbox Code Playgroud)

这个应用程序只是每秒向标准输出打印一行。您可以看到输出文件是如何写入的,例如使用tail -f /tmp/out.

请注意,您可以根据自己的喜好(以及test.sh脚本指示的内容)使用其他 shell 来执行脚本。

例如使用bash

cmd := exec.Command("/bin/bash", "-c", "/tmp/test.sh > /tmp/out")
// rest is unchanged
Run Code Online (Sandbox Code Playgroud)

请注意,要由 shell 执行的命令作为单个string参数传递,并且不会像直接在命令提示符中执行时那样分解为多个。