nohup 返回到 Golang 程序中

huangapple go评论80阅读模式
英文:

nohup return to back to program in golang

问题

我们正在尝试从Golang执行一个nohup脚本,以下是我们执行的命令:

cmd := exec.Command("nohup", "sh", destinationDirPath + "/pf_file_monitor.sh", "&>", destinationDirPath + "/nohup.out", "&")
_, err = cmd.Output();

问题是,在执行这个命令后,控制权没有返回到程序中。

请问有人可以帮助我吗?

英文:

We are trying to excute a nohup script from the golang and here is the command we excute

cmd := exec.Command("nohup","sh",destinationDirPath + "/pf_file_monitor.sh","&>",destinationDirPath + "/nohup.out","&")
_,err = cmd.Output();

The problem is after excuting this command the control is not returing back to the program.

Can anyone please assist me in this ?

答案1

得分: 2

所以看起来有几个问题让你困惑了。我已经重新编写了下面的代码,但是让我先明确解释一下每个问题,这样我就可以解释混淆的原因并解释我的更改:

  • destinationDirPath + "/pf_file_monitor.sh" - 这在技术上没有错,但使用filepath.Join更符合惯用法(也更可靠);作为一般规则,除非有充分的理由,否则不应该手动拼接路径字符串。
  • $> - 我猜你在这里尝试的是将命令的输出重定向到日志文件。问题在于,符号$>只在shell(如shbash)中有意义。而Go则将其视为另一个命令行参数,并将其作为参数传递给程序。因此,你需要手动处理这个问题。在我下面给出的示例中,我打开文件,然后将cmd的stdout和stderr管道(这些是控制stdout和stderr去向的io.Writer)设置为文件句柄。
  • 它不会在后台运行。问题在于你使用了Run方法,它会运行命令并阻塞直到完成。相反,你应该使用Start方法,它只是启动命令然后立即返回,这样你的程序就可以继续运行。

希望这可以帮到你!这是更新后的实现:

script := filepath.Join(destinationDirPath, "pf_file_monitor.sh")
log := filepath.Join(destinationDirPath, "nohup.out")
cmd := exec.Command("nohup", "sh", script)

f, err := os.Create(log)
if err != nil {
    // 处理错误
}

// 将stdout和stderr都重定向到日志文件
cmd.Stdout = f
cmd.Stderr = f

// 启动命令(并在后台运行)
err = cmd.Start()
if err != nil {
    // 处理错误
}
英文:

So it seems that there are a few things that are tripping out up. I've rewritten the code below, but let me first address each one explicitly so I can explain what I think the confusion is and explain my changes:

  • destinationDirPath + "/pf_file_monitor.sh" - this isn't technically wrong, but it's much more idiomatic (and more reliable) to use filepath.Join; as a general rule, you should never be doing manual string concatenation of paths unless you have a good reason
  • $> - I assume what you're trying to do here is redirect the output of the command to the log file. The issue here is that the symbol $> is only meaningful when you're in a shell (like sh or bash). Go, on the other hand, just sees it as another command line argument, and passes it as an argument to the program. Thus, you're going to have to do this manually. In the example I give below, what I do is open the file up and then set cmd's stdout and stderr pipes (these are io.Writers that control where stdout and stderr go) to the file handle.
  • It won't run in the background. The problem here is that you're using the Run method, which will run the command and block until it finishes. You instead want the Start method, which only starts the command and then immediately returns so your program can keep running.

Hope this helps! Here's the updated implementation:

script := filepath.Join(destinationDirPath, "pf_file_monitor.sh")
log := filepath.Join(destinationDirPath, "nohup.out")
cmd := exec.Command("nohup", "sh", script)

f, err := os.Create(log)
if err != nil {
	// handle error
}

// redirect both stdout and stderr to the log file
cmd.Stdout = f
cmd.Stderr = f

// start command (and let it run in the background)
err = cmd.Start()
if err != nil {
	// handle error
}

答案2

得分: 0

这是原始命令:

nohup ./tools migrate --offset 1 >> ./migrate_`date +%Y%m%d%H%M`.log 2>&1 &

这是我的实现:

	var command *exec.Cmd
	var date = time.Now().Format("200601021504")
	logFileName := "migrate_" + date + ".log"
	logFile, err := os.OpenFile(logFileName, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0755)
	if err != nil {
		return
	}
	var arg = strings.Split("migrate --offset=1", " ")
	command = exec.Command("./tools", arg...)
	command.Stdout = logFile
	command.Stderr = logFile
	err = command.Start()
	if err != nil {
		return
	}

它可以正常工作。

英文:

This is the original command

nohup ./tools migrate --offset 1 >> ./migrate_`date +%Y%m%d%H%M`.log 2>&1 &

This is my realization


	var command *exec.Cmd
	var date = time.Now().Format("200601021504")
	logFileName := "migrate_"+date+".log"
	logFile, err := os.OpenFile(logFileName, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0755)
	if err != nil {
		return
	}
	var arg = strings.Split("migrate --offset=1", " ")
	command = exec.Command("./tools", arg...)
	command.Stdout = logFile
	command.Stderr = logFile
	err = command.Start()
	if err != nil {
		return
	}

It works

huangapple
  • 本文由 发表于 2015年11月26日 15:10:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/33932531.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定