我试图在一个分离的进程中启动一个命令,以便它可以在 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。
有没有办法实现这样的重定向?
您可以启动一个 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参数传递,并且不会像直接在命令提示符中执行时那样分解为多个。