discovery_linux.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. //go:build linux
  2. package discovery
  3. import (
  4. "fmt"
  5. "os/exec"
  6. "regexp"
  7. "sort"
  8. "strconv"
  9. "strings"
  10. "ai-status-light/internal/logger"
  11. )
  12. func findByPID() []int {
  13. var ports []int
  14. pidRegex := regexp.MustCompile(`(?:^|/)opencode(?:\s|$)`)
  15. out, err := exec.Command("ps", "aux").Output()
  16. if err != nil {
  17. logger.Debug("执行 ps aux 失败: %v", err)
  18. return ports
  19. }
  20. var pids []int
  21. for _, line := range strings.Split(string(out), "\n") {
  22. if pidRegex.MatchString(line) && !strings.Contains(line, "grep") {
  23. fields := strings.Fields(line)
  24. if len(fields) > 1 {
  25. if pid, err := strconv.Atoi(fields[1]); err == nil {
  26. pids = append(pids, pid)
  27. }
  28. }
  29. }
  30. }
  31. if len(pids) == 0 {
  32. logger.Debug("未找到 opencode 进程")
  33. return ports
  34. }
  35. logger.Debug("发现 opencode 进程 PID: %v", pids)
  36. for _, pid := range pids {
  37. ssOut, err := exec.Command("ss", "-tlnp").Output()
  38. if err != nil {
  39. logger.Debug("执行 ss -tlnp 失败: %v", err)
  40. continue
  41. }
  42. for _, line := range strings.Split(string(ssOut), "\n") {
  43. if strings.Contains(line, fmt.Sprintf("pid=%d", pid)) {
  44. fields := strings.Fields(line)
  45. for _, f := range fields {
  46. if strings.Contains(f, ":") {
  47. parts := strings.Split(f, ":")
  48. if len(parts) == 2 {
  49. if port, err := strconv.Atoi(parts[1]); err == nil {
  50. if port > 0 && port < 65535 && !contains(ports, port) {
  51. ports = append(ports, port)
  52. }
  53. }
  54. }
  55. }
  56. }
  57. }
  58. }
  59. }
  60. sort.Ints(ports)
  61. return ports
  62. }
  63. func findByCmdline() []int {
  64. var ports []int
  65. out, err := exec.Command("ps", "aux").Output()
  66. if err != nil {
  67. logger.Debug("执行 ps aux 失败: %v", err)
  68. return ports
  69. }
  70. for _, line := range strings.Split(string(out), "\n") {
  71. if strings.Contains(line, "opencode") && !strings.Contains(line, "opencode-monitor") && !strings.Contains(line, "grep") {
  72. if strings.Contains(line, "--port") {
  73. fields := strings.Fields(line)
  74. for i, f := range fields {
  75. if f == "--port" && i+1 < len(fields) {
  76. if port, err := strconv.Atoi(fields[i+1]); err == nil {
  77. if !contains(ports, port) {
  78. ports = append(ports, port)
  79. }
  80. }
  81. }
  82. }
  83. }
  84. }
  85. }
  86. sort.Ints(ports)
  87. return ports
  88. }