【问题标题】:Go Auto-Recompile and Reload Server on file change在文件更改时自动重新编译和重新加载服务器
【发布时间】:2013-11-05 11:18:15
【问题描述】:

我知道 AppEngine 会这样做,但我不会为它编写代码。

我尝试使用来自 Ruby 世界的 Guard 来监听 .go 文件的变化,并执行以下命令:

killall foo
go build -race
./foo &

但它从不将foo 发送到后台,它只是无限期挂起。

你们是如何解决这个问题的?解决方案也必须是跨平台的(GNU/Linux 和 Mac)。

【问题讨论】:

  • 不是真正的“Go”问题,你试过了吗:nohup ./foo > /var/log/foo/out.log &
  • @MartinGallagher 谢谢,它有效。

标签: go guard


【解决方案1】:

一位朋友为 go 编写了一个简单的编译守护程序,对我自己的小型网络/http-projects 来说就像一个魅力。

您可以在此处找到存储库:https://github.com/githubnemo/CompileDaemon

【讨论】:

  • 看起来它不运行二进制文件,它只构建它们。还有其他解决方案可以帮助我们完成剩下的工作吗?
  • 这是旧答案,但 CompileDaemon 也使用CompileDaemon -command="./MyProgram -my-options" 运行它
  • 编译守护进程很好,但据我了解,它无法在没有构建的情况下运行命令。在某些情况下,您只需要运行“go run ./my_app”而不先构建它。在这种情况下,编译守护进程是无用的。
【解决方案2】:

您也可以试试 Codegangsta 的 Gin。火了就忘了。

https://github.com/codegangsta/gin

编辑: 我现在更喜欢CompileDaemon。 Gin 有时不接受请求

【讨论】:

    【解决方案3】:

    我最近发现了一个reflex 工具。它速度很快,而且效果很好。它与nodemon(来自nodejs world)和guard(来自ruby world)非常相似。

    大部分时间我都在使用它,如下所示:

    reflex -d none -s -R vendor. -r \.go$ -- go run cmd/server/main.go

    但是将它的选项放在像 .reflex 这样的文件中可能更方便,其内容如下:

    -d none -s -R vendor. -r \.go$

    那么你就这样运行它

    reflex $(cat .reflex) -- go run cmd/server/main.go

    你可以对“热重载”测试做同样的事情:

    reflex $(cat .reflex) -- go test ./... -v

    还有一个配置选项,您可以在其中指定同时运行的多个命令,但我并没有真正使用它。

    【讨论】:

    • 看来reflex(现在)可以直接读取配置文件了。您的第三个示例可以重写为reflex -c .reflex -- go run cmd/server/main.go
    • 感谢@ESV,没有注意到这种变化,很高兴知道这一点。
    • 而且它仅适用于 Linux。 :(
    • 好吧,它也适用于 OSX,不过从未尝试过 Windows。
    【解决方案4】:

    如果有人还在寻找解决方案,我编写了一些 shell 脚本来执行此操作,并且可以通过 docker 环境使用它,repos at https://github.com/zephinzer/golang-dev

    【讨论】:

      【解决方案5】:

      您可以为此使用nodemon。只需创建一个 nodemon.json 文件,其中包含您的配置、要监视的文件、要忽略的文件以及文件更改时要执行的命令。类似这样的配置。

      nodemon.json

      {
        "watch": ["*"],
        "ext": "go graphql",
        "ignore": ["*gen*.go"],
        "exec": "go run scripts/gqlgen.go && (killall -9 server || true ) && go run ./server/server.go"
      }
      

      您确实需要 nodejs 才能使其工作。
      但它比我迄今为止使用的任何其他特定工具都要好。

      【讨论】:

      • 这是救命稻草,谢谢。使用 nodemon 比标准的 appengine 文件观察器要好得多。这是对我感兴趣的“python dev_appserver.py app/--automatic_restart=no”的 exec 命令
      【解决方案6】:

      在 GO 世界中有 2 个主要竞争者 freshglide

      但我会选择Fresh https://github.com/gravityblast/fresh

      【讨论】:

      • 为什么选择fresh 而不是glide?是什么让您比CompileDaemonreflex 更有吸引力?
      【解决方案7】:

      在互联网上滚动寻找一个使用标准 linux 工具(inotify 和 bash)的简单解决方案后,我最终创建了这个简单的 bash 脚本来完成这项工作。

      我在运行 golang:1.12 并使用 go run . 提供文件的容器中对其进行了测试。在使用之前阅读脚本,因为它会根据文件夹名称杀死 go run 进程,如果与您运行的其他进程发生冲突,它可能会杀死它们。

      #!/bin/bash
      
      go run . &
      while inotifywait --exclude .swp -e modify -r . ;
      do
          # find PID of the file generated by `go run .` to kill it. make sure the grep does not match other processes running on the system
          IDS=$(ps ax | grep "/tmp/go-build" | grep "b001/exe/main" | grep -v "grep" | awk '{print $1}')
          if [ ! -z "$IDS" ]
          then
              kill $IDS;
          fi
          go run . &
      done;
      

      【讨论】:

      • 仅当程序在当前目录树中被修改时才有效。如果一个包位于 fs 中的其他位置被修改,这不会重新启动应用程序。这样的smthg更聪明github.com/clementauger/grelot
      • 我喜欢 --exclude .swp... VI 的乐趣。
      【解决方案8】:

      另一个选项,如果你的机器上安装了 nodejs

      使用 -g npm i -g nodemon 安装 nodemon

      转到您的代码目录并运行:

      nodemon --watch './**/*.go' --signal SIGTERM --exec 'go' run cmd/MyProgram/main.go
      

      这将在每次任何.go 文件更改时发送 SIGTERM 并将运行 go run cmd/Myprogram/main.go

      完全跨平台。

      【讨论】:

      • 但是,正确地安装npm可能会很棘手(并且特定于平台)。 nvm 可能是获取npm 的最佳方式:npm throws error without sudo
      • NPM 是完全跨平台的,如果您将 npm 与 sudo 一起使用,您只是安装错误。 NVM 不解决跨平台问题,它解决了版本控制
      • 就像在节点世界中的魅力一样。
      • 就我而言,我必须使用 -e 指定扩展名:nodemon -e go --signal SIGTERM --exec 'go' run .
      • 完美。正是我想要的
      【解决方案9】:

      我使用了一个名为entr的工具

      安装brew install entr (mac)
      或者,sudo apt-get install entr (linux)

      要重新编译并运行.go 文件更改,请运行以下命令...

      ls **/*.go | entr go run main.go
      

      【讨论】:

      • 这个命令的问题是它不能捕获新文件。它只监视初步 ls 中列出的文件。
      【解决方案10】:

      有一个go版本的nodemon:https://github.com/mitranim/gow

      go install github.com/mitranim/gow@latest
      

      用法

      # Start and restart on change
      gow run .
      
      # Pass args to the program
      gow run . arg0 arg1 ...
      
      # Run subdirectory
      gow run ./subdir
      
      # Vet and re-vet on change; verbose mode is recommended
      gow -v vet
      
      # Clear terminal on restart
      gow -c run .
      
      # Specify file extension to watch
      gow -e=go,mod,html run .
      
      # Help
      gow -h
      

      【讨论】:

        【解决方案11】:

        最好的选择是在你的机器上安装nodejs 并使用nodemon

        使用 -g sudo npm install -g nodemon 安装 nodemon 还要使用 sudo 来避免任何写权限

        现在转到您的程序目录并运行:

        nodemon --watch './**/*.go' --signal SIGTERM --exec 'go' run path-to-the-main-file-of-go-program-with-extension
        

        这将在每次任何.go 文件更改时发送 SIGTERM 并将运行 go run main-go-file-of-program-with-extension

        完全跨平台。 这将适用于任何编程语言,只需将命令更改为

        nodemon --watch './**/*.extension-of-programming-file-without-preceeding-dot' --signal SIGTERM --exec 'go' run path-to-the-main-file-of-program-with-extension
        

        【讨论】:

          猜你喜欢
          • 2018-06-01
          • 2012-07-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-12-25
          • 1970-01-01
          • 2016-05-16
          • 1970-01-01
          相关资源
          最近更新 更多