英文:
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(如sh
或bash
)中有意义。而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 usefilepath.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 (likesh
orbash
). 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 setcmd
's stdout and stderr pipes (these areio.Writer
s 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 theStart
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论