nohup return 回到 golang 程序
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();
问题是在执行此命令后,控制没有返回到程序。
任何人都可以帮助我吗?
所以似乎有一些事情被绊倒了。我已经重写了下面的代码,但让我首先明确地解决每个问题,这样我就可以解释我认为的混淆是什么并解释我的更改:
destinationDirPath + "/pf_file_monitor.sh"
- 这在技术上没有错,但使用 filepath.Join
更符合习惯(也更可靠);作为一般规则,除非你有充分的理由,否则你永远不应该对路径进行手动字符串连接
$>
- 我假设您在这里尝试做的是将命令的输出重定向到日志文件。这里的问题是符号 $>
仅当您处于 shell 时才有意义(例如 sh
或 bash
)。另一方面,Go 只是将其视为另一个命令行参数,并将其作为参数传递给程序。因此,您将不得不手动执行此操作。在下面给出的示例中,我所做的是打开文件,然后将 cmd
的 stdout 和 stderr 管道(这些 io.Writer
控制 stdout 和 stderr 的位置)设置为文件句柄.
- 它不会 运行 在后台。这里的问题是你正在使用
Run
method, which will run the command and block until it finishes. You instead want the Start
方法,它只启动命令然后立即 returns 所以你的程序可以保持 运行ning.
希望对您有所帮助!这是更新后的实现:
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
}
这是原来的命令
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
}
有效
我们正在尝试从 golang 执行 nohup 脚本,这是我们执行的命令
cmd := exec.Command("nohup","sh",destinationDirPath + "/pf_file_monitor.sh","&>",destinationDirPath + "/nohup.out","&")
_,err = cmd.Output();
问题是在执行此命令后,控制没有返回到程序。
任何人都可以帮助我吗?
所以似乎有一些事情被绊倒了。我已经重写了下面的代码,但让我首先明确地解决每个问题,这样我就可以解释我认为的混淆是什么并解释我的更改:
destinationDirPath + "/pf_file_monitor.sh"
- 这在技术上没有错,但使用filepath.Join
更符合习惯(也更可靠);作为一般规则,除非你有充分的理由,否则你永远不应该对路径进行手动字符串连接$>
- 我假设您在这里尝试做的是将命令的输出重定向到日志文件。这里的问题是符号$>
仅当您处于 shell 时才有意义(例如sh
或bash
)。另一方面,Go 只是将其视为另一个命令行参数,并将其作为参数传递给程序。因此,您将不得不手动执行此操作。在下面给出的示例中,我所做的是打开文件,然后将cmd
的 stdout 和 stderr 管道(这些io.Writer
控制 stdout 和 stderr 的位置)设置为文件句柄.- 它不会 运行 在后台。这里的问题是你正在使用
Run
method, which will run the command and block until it finishes. You instead want theStart
方法,它只启动命令然后立即 returns 所以你的程序可以保持 运行ning.
希望对您有所帮助!这是更新后的实现:
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
}
这是原来的命令
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
}
有效