本文展示一個輕量級的 Go HTTP 服務,透過呼叫系統 lsof 指令查詢指定路徑的檔案開啟狀態,並回傳行數統計。適合作為系統監控或除錯工具的參考實作。
package main
import (
"fmt"
"net/http"
"os/exec"
"flag"
)
func main() {
http.HandleFunc("/", readHandle)
port := flag.Int("port", 2012, "Listen Port")
flag.Parse()
http.ListenAndServe(fmt.Sprintf(":%d", *port), nil)
}
func readHandle(w http.ResponseWriter, r *http.Request) {
// 1. 建立 lsof 指令,參數為查詢路徑
lsof := exec.Command("lsof", r.FormValue("path"))
// 2. 建立 wc -l 指令計算行數
wc := exec.Command("wc", "-l")
// 3. 管道串接:lsof stdout -> wc stdin
lsofOut, _ := lsof.StdoutPipe()
lsof.Start()
wc.Stdin = lsofOut
out, _ := wc.Output()
// 4. 回傳結果
fmt.Fprintf(w, "%v", r.FormValue("path"))
fmt.Fprintf(w, "%s", out)
fmt.Fprintf(w, "%s", r.URL.Path[1:])
}
flag 套件解析命令列參數 -port,預設 2012。http.HandleFunc("/", readHandle) 註冊根路徑處理器。http.ListenAndServe 啟動阻塞式監聽。Go 的 os/exec 提供優雅的管道支援:
lsof.StdoutPipe() 取得標準輸出管道。lsof.Start() 非阻塞啟動 lsof 進程。wc.Stdin,實現 lsof | wc -l 的管道效果。wc.Output() 等待管道結束並收集輸出。此設計避免了中間資料落地,記憶體效率高。
r.FormValue("path") 取得查詢字串或表單中的 path 參數。lsof 輸出行數、請求 URL 路徑(去除首字元 /)。# 啟動服務
go run main.go -port=8080
# 查詢 /var/log/syslog 被開啟的情況
curl "https://localhost:8080/?path=/var/log/syslog"
StdoutPipe、Start、Output 的錯誤回傳,生產環境需完善。exec.Command,存在指令注入風險,應對路徑進行清理或使用白名單。lsof 進程,建議加入信號量限制。lsof 僅限 Unix-like 系統,Windows 需改用 handle.exe 或其他工具。這個範例展示了 Go 語言處理系統指令管道、建立 HTTP 服務的簡潔性。只要補強安全性與健壯性,即可演變為實用的系統偵測微服務。