package main import ( "bufio" "flag" "fmt" "os" "os/exec" "strconv" "strings" ) func commandExists(cmd string) (string, bool) { path, err := exec.LookPath(cmd) if err != nil { return "", false } return path, true } func ss(p int) { cmdStr, ok := commandExists("ss") if !ok { fmt.Printf("ss command not found") } output, err := exec.Command(cmdStr, "-tulpn").Output() if err != nil { fmt.Printf("failed to execute ss command: %v", err) return } reader := strings.NewReader(string(output)) scanner := bufio.NewScanner(bufio.NewReader(reader)) matches := []string{} i := 0 for scanner.Scan() { if i == 0 { matches = append(matches, scanner.Text()) } if strings.Contains(scanner.Text(), ":"+strconv.Itoa(p)) { matches = append(matches, scanner.Text()) } i++ } fmt.Println(strings.Join(matches, "\n")) } func dockerPs(compose bool) { var s string if !compose { s = "docker" } else { s = "docker-compose" } cmd, ok := commandExists(s) if !ok { fmt.Printf("%s not found", s) } output, err := exec.Command(cmd, "ps").Output() if err != nil { fmt.Printf("failed to execute docker command: %v", err) } fmt.Println(string(output)) } const ( portType string = "port" dockerType string = "docker" ) func main() { port := func(args []string) { fs := flag.NewFlagSet("port", flag.ContinueOnError) port := fs.Int("p", 0, "non-zero port to search for") if err := fs.Parse(args); err != nil { fmt.Println(err) return } if *port == 0 { fmt.Println("Cannot search port 0") return } ss(*port) } docker := func(args []string) { fs := flag.NewFlagSet("docker", flag.ContinueOnError) compose := fs.Bool("c", false, "use docker compose instead") if err := fs.Parse(args); err != nil { fmt.Println(err) return } dockerPs(*compose) } args := os.Args subArgs := args[2:] switch args[1] { case portType: port(subArgs) case dockerType: docker(subArgs) default: fmt.Println("Unknown command type. Supported types are 'port'.") } } var port int func init() { flag.IntVar(&port, "port", 0, "search procs running on this port") flag.Parse() }