entr和go run不兼容。

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

entr and go run not playing nice

问题

我正在使用go进行一些轻量级的Web开发,并在使用entr时遇到了问题。我在一个目录中编辑.go文件,同时在另一个终端窗口中运行以下命令:

  1. ls *.go | entr -r go run *.go

我可以看到每次保存文件时它都会重新启动我的程序,因为每次保存时一些格式化语句都会打印到终端上。然而,每当我导航到localhost:8080时,我看到的是启动entr时存在的处理程序内容(而不是最近更改的内容)。如果我按下Ctrl+C,然后重新启动entr,我就可以看到最新的更改。

你知道我做错了什么吗?

这是一个最简化的示例:

  1. // test.go
  2. package main
  3. import (
  4. "fmt"
  5. "net/http"
  6. )
  7. func handler(w http.ResponseWriter, r *http.Request) {
  8. fmt.Fprintf(w, "Hello there! I love %s!", r.URL.Path[1:])
  9. }
  10. func main() {
  11. fmt.Println("Starting up...")
  12. http.HandleFunc("/", handler)
  13. http.ListenAndServe(":8080", nil)
  14. }

现在,如果我运行ls test.go | entr -r go run test.go,我会在终端上看到Starting up...的输出,并且我可以访问localhost:8080/tests,看到一个页面显示"Hello there! I love tests!"。如果我更改handler函数,使其变为:

  1. func handler(w http.ResponseWriter, r *http.Request) {
  2. fmt.Fprintf(w, "I guess %s are ok...", r.URL.Path[1:])
  3. }

我会再次在终端上看到Starting up...的消息,但是访问localhost:8080/tests仍然会显示"Hello there! I love tests!"的页面(即使在隐身模式下)。如果我杀死entr进程并重新启动它,我就可以访问localhost:8080/tests,看到预期的I guess tests are ok...

编辑

ListenAndServe中获取错误可以确认这与悬空套接字有关。

  1. ...
  2. err := http.ListenAndServe(":8080", nil)
  3. fmt.Printf("ListenAndServe ERR: %s\n", err)
  4. ...

在终端上显示额外的一行:

  1. listen tcp :8080: bind: address already in use

快速搜索告诉我,没有一种简单的方法可以停止使用ListenAndServe启动的监听器。是否有比这个更简单的方法?

英文:

I'm doing some light web development in go, and running into a problem with entr. I'm editing .go files in a directory while having

  1. ls *.go | entr -r go run *.go

running in a separate terminal window.

I can see it re-starting my program every time I save a file, because some format statements get printed out to the terminal every time I do so. However, whenever I navigate to localhost:8080, I see the handler content that was present when I started entr (rather than the content in the most recent change). If I Ctrl+C, then restart entr, I see the latest changes.

Any idea what I'm doing wrong?

Here's the minimal example:

  1. // test.go
  2. package main
  3. import (
  4. "fmt"
  5. "net/http"
  6. )
  7. func handler (w http.ResponseWriter, r *http.Request) {
  8. fmt.Fprintf(w, "Hello there! I love %s!", r.URL.Path[1:])
  9. }
  10. func main() {
  11. fmt.Println("Starting up...")
  12. http.HandleFunc("/", handler)
  13. http.ListenAndServe(":8080", nil)
  14. }

Now, if I run ls test.go | entr -r go run test.go, I see Starting up... printed to the terminal, and I can go to localhost:8080/tests to see a page that says "Hello there! I love tests!". If I change the handler function so that it reads

  1. func handler (w http.ResponseWriter, r *http.Request) {
  2. fmt.Fprintf(w, "I guess %s are ok...", r.URL.Path[1:])
  3. }

I see the Starting up... message printed in terminal again, but going to localhost:8080/tests still gives me the page showing "Hello there! I love tests!" (even in incognito mode). If I then kill the entr process and restart it, I can go to localhost:8080/tests to see I guess tests are ok... as expected.

Edit:

Getting the error out of ListenAndServe confirms that this has to do with a dangling socket.

  1. ...
  2. err := http.ListenAndServe(":8080", nil)
  3. fmt.Printf("ListenAndServe ERR: %s\n", err)
  4. ...

shows the extra line

  1. listen tcp :8080: bind: address already in use

in terminal. A quick search tells me that there isn't an easy way to stop a listener started with ListenAndServe. Is there a simpler approach than this?

答案1

得分: 2

ls命令只会列出当前目录中的go文件。要监听项目中所有子文件夹中的go文件,命令应该像这样:

  1. find . | grep '\.go' | entr -r go run .
英文:

The ls command only lists the go files in your current directory. The command should be like this to listen to go files in all subfolders in the project.

  1. find . | grep '\.go' | entr -r go run .

答案2

得分: 1

问题:
go run将在一个单独的进程中启动服务器,该进程不会被终止。

解决方案:
使用一个小脚本来终止并启动服务器

  1. #!/bin/sh
  2. pkill "$1"
  3. go run "$1.go"

并将其用于entr

英文:

The problem:
go run will start the server in a separate process which won't be killed.

A solution:
Use a little script which kills and starts the server

  1. #!/bin/sh
  2. pkill "$1"
  3. go run "$1.go"

and use this for entr.

答案3

得分: 1

在Linux中创建了两个进程。第一个是go run main.go,第二个是/tmp/go-build/<随机数>b001/exe/main。需要杀死第二个进程来终止程序,而不是第一个进程...

英文:

In linux there are two process created. First is the go run main.go and the second is the /tmp/go-build/<random number>b001/exe/main. The second one needs to be killed to terminate the program not the first...

huangapple
  • 本文由 发表于 2015年3月25日 00:05:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/29237500.html
匿名

发表评论

匿名网友

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

确定