首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Go 語言實作 lsof HTTP 服務:查詢檔案開啟狀態

     編輯:關於C語言

專案簡介

本文展示一個輕量級的 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:])
}

核心機制解析

1. HTTP 服務啟動

  • 使用 flag 套件解析命令列參數 -port,預設 2012。
  • http.HandleFunc("/", readHandle) 註冊根路徑處理器。
  • http.ListenAndServe 啟動阻塞式監聽。

2. 管道化指令執行

Go 的 os/exec 提供優雅的管道支援:

  1. lsof.StdoutPipe() 取得標準輸出管道。
  2. lsof.Start() 非阻塞啟動 lsof 進程。
  3. 將管道指派給 wc.Stdin,實現 lsof | wc -l 的管道效果。
  4. wc.Output() 等待管道結束並收集輸出。

此設計避免了中間資料落地,記憶體效率高。

3. 請求參數處理

  • 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 服務的簡潔性。只要補強安全性與健壯性,即可演變為實用的系統偵測微服務。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved