我在本地构建了 golang 应用程序,然后scp到服务器。我需要停止该过程并手动重新启动。有没有办法在二进制文件更新时自动重启进程?
虽然这通常最好使用 daemontools 或类似的东西在进程外实现,但在某些情况下,您希望/需要在程序内部完成。
根据程序特性(例如连接或可能打开的文件等),在程序中执行此操作可能会很棘手。
话虽如此,这里有一个在大多数情况下都可以工作的实现:
package main
import (
"log"
"os"
"syscall"
"time"
"github.com/fsnotify/fsnotify"
"github.com/kardianos/osext"
)
func setupWatcher() (chan struct{}, error) {
file, err := osext.Executable()
if err != nil {
return nil, err
}
log.Printf("watching %q\n", file)
w, err := fsnotify.NewWatcher()
if err != nil {
return nil, err
}
done := make(chan struct{})
go func() {
for {
select {
case e := <-w.Events:
log.Printf("watcher received: %+v", e)
err := syscall.Exec(file, os.Args, os.Environ())
if err != nil {
log.Fatal(err)
}
case err := <-w.Errors:
log.Printf("watcher error: %+v", err)
case <-done:
log.Print("watcher shutting down")
return
}
}
}()
err = w.Add(file)
if err != nil {
return nil, err
}
return done, nil
}
func main() {
log.Print("program starting")
watcher, err := setupWatcher()
if err != nil {
// do something sensible
log.Fatal(err)
}
// continue with app startup
time.Sleep(100 * time.Minute) // just for testing
// eventually you may need to end the watcher
close(watcher) // this way you can
}
Run Code Online (Sandbox Code Playgroud)
然后你做
% go build main.go
% ./main
2016/12/29 14:15:06 program starting
2016/12/29 14:15:06 watching "/home/plalloni/tmp/v/main"
Run Code Online (Sandbox Code Playgroud)
这是在您(在其他终端中)运行(在其他终端中)一些连续的“go build main.go”(“更新”正在运行的二进制文件)后产生的输出。
2016/12/29 14:15:32 watcher received: "/home/plalloni/tmp/v/main": CHMOD
2016/12/29 14:15:32 program starting
2016/12/29 14:15:32 watching "/home/plalloni/tmp/v/main"
2016/12/29 14:15:38 watcher received: "/home/plalloni/tmp/v/main": CHMOD
2016/12/29 14:15:38 program starting
2016/12/29 14:15:38 watching "/home/plalloni/tmp/v/main"
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你。
| 归档时间: |
|
| 查看次数: |
7817 次 |
| 最近记录: |