Go 使用重定向到文件启动分离的命令
我正在尝试在分离的进程中启动一个命令,以便在go程序退出后继续。我需要将命令的输出重定向到一个文件 我需要的是这样的东西:Go 使用重定向到文件启动分离的命令,go,process,io,Go,Process,Io,我正在尝试在分离的进程中启动一个命令,以便在go程序退出后继续。我需要将命令的输出重定向到一个文件 我需要的是这样的东西: func main() { command := exec.Command("/tmp/test.sh", ">", "/tmp/out") if err := command.Start(); err != nil { fmt.Fprintln(os.Stderr, "Command failed.", err) o
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)
}
显然,这样的重定向不起作用。由于启动长时间运行的命令后立即退出程序,因此无法打开文件并将其绑定到Stdout
有没有办法实现这样的重定向?也许您可以尝试使用以下方法: 打开一个文件(和
os.file
实现io.Writer
),然后将其作为命令传递。Stdout
可以实现以下功能:
func main() {
command := exec.Command("./tmp/test.sh")
f, err := os.OpenFile("/tmp/out", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
fmt.Printf("error opening file: %v", err)
}
defer f.Close()
// On this line you're going to redirect the output to a file
command.Stdout = f
if err := command.Start(); err != nil {
fmt.Fprintln(os.Stderr, "Command failed.", err)
os.Exit(1)
}
fmt.Println("Process ID:", command.Process.Pid)
}
我不确定这对你的情况来说是否是一个可行的解决方案。我在当地试过,似乎很管用。。。请记住,您的用户应该能够创建/更新该文件。您可以启动一个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)
用这个简单的Go应用程序测试它(用编译成的可执行二进制文件的名称替换/tmp/Test.sh
):
请注意,shell要执行的命令是作为单个
字符串
参数传递的,它不会像在命令提示符下直接执行命令那样分解为多个参数。这是可行的,但我不理解为什么。进程关闭后如何写入文件?如果这不重要,我们为什么要打开它呢?我没想过。所以,我会调查并返回给您,但我正在阅读文档,exec.Cmd和我们重定向的stdout是由一个writer描述符管理的,我相信,它会负责关闭它(看起来也会打开它…):谢谢您的回答。虽然你的答案没有错,但我还是同意@thoeni的答案,因为它是windows和linux的单一解决方案,对我来说更方便。如果我们需要使用操作系统提供的标准输出和文件重定向,触发后不需要在实际进程之上运行另一个go进程,这是很好的。谢谢
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)
}
}
cmd := exec.Command("/bin/bash", "-c", "/tmp/test.sh > /tmp/out")
// rest is unchanged