英文:
entr and go run not playing nice
问题
我正在使用go进行一些轻量级的Web开发,并在使用entr时遇到了问题。我在一个目录中编辑.go文件,同时在另一个终端窗口中运行以下命令:
ls *.go | entr -r go run *.go
我可以看到每次保存文件时它都会重新启动我的程序,因为每次保存时一些格式化语句都会打印到终端上。然而,每当我导航到localhost:8080时,我看到的是启动entr时存在的处理程序内容(而不是最近更改的内容)。如果我按下Ctrl+C,然后重新启动entr,我就可以看到最新的更改。
你知道我做错了什么吗?
这是一个最简化的示例:
// test.go
package main
import (
	"fmt"
	"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello there! I love %s!", r.URL.Path[1:])
}
func main() {
	fmt.Println("Starting up...")
	http.HandleFunc("/", handler)
	http.ListenAndServe(":8080", nil)
}
现在,如果我运行ls test.go | entr -r go run test.go,我会在终端上看到Starting up...的输出,并且我可以访问localhost:8080/tests,看到一个页面显示"Hello there! I love tests!"。如果我更改handler函数,使其变为:
func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "I guess %s are ok...", r.URL.Path[1:])
}
我会再次在终端上看到Starting up...的消息,但是访问localhost:8080/tests仍然会显示"Hello there! I love tests!"的页面(即使在隐身模式下)。如果我杀死entr进程并重新启动它,我就可以访问localhost:8080/tests,看到预期的I guess tests are ok...。
编辑:
从ListenAndServe中获取错误可以确认这与悬空套接字有关。
...
   err := http.ListenAndServe(":8080", nil)
   fmt.Printf("ListenAndServe ERR: %s\n", err)
...
在终端上显示额外的一行:
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
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:
// test.go
package main
import (
	"fmt"
	"net/http"
)
func handler (w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello there! I love %s!", r.URL.Path[1:])
}
func main() {
	fmt.Println("Starting up...")
	http.HandleFunc("/", handler)
	http.ListenAndServe(":8080", nil)
}
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
func handler (w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "I guess %s are ok...", r.URL.Path[1:])
}
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.
...
   err := http.ListenAndServe(":8080", nil)
   fmt.Printf("ListenAndServe ERR: %s\n", err)
...
shows the extra line
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文件,命令应该像这样:
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.
find . | grep '\.go' | entr -r go run .
答案2
得分: 1
问题:
go run将在一个单独的进程中启动服务器,该进程不会被终止。
解决方案:
使用一个小脚本来终止并启动服务器
#!/bin/sh
pkill "$1"
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
#!/bin/sh
pkill "$1"
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...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论