entr和go run不兼容。

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

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...

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:

确定