diff --git a/lib/completions.sh b/lib/completions.sh index ccc7e8d..49d280b 100644 --- a/lib/completions.sh +++ b/lib/completions.sh @@ -2,7 +2,7 @@ _u7_complete_entities() { local verb="$1" cur="$2" case "$verb" in show|sh) - COMPREPLY=($(compgen -W "ip csv json line ssl files diff cpu memory disk processes port usage network git env log http docker system definition functions --help" -- "$cur")) + COMPREPLY=($(compgen -W "ip csv json line ssl files diff cpu memory disk processes ports port usage network git env log http docker system definition functions --help" -- "$cur")) ;; make|mk) COMPREPLY=($(compgen -W "dir file password user copy link archive clone template sequence --help" -- "$cur")) @@ -38,6 +38,7 @@ _u7_complete_args() { env) COMPREPLY=($(compgen -W "match" -- "$cur")) ;; http) COMPREPLY=($(compgen -W "get head headers" -- "$cur")) ;; docker) COMPREPLY=($(compgen -W "containers images volumes networks all" -- "$cur")) ;; + ports) COMPREPLY=($(compgen -W "match" -- "$cur")) ;; log) COMPREPLY=($(compgen -W "limit match follow" -- "$cur")) ; _filedir ;; *) _filedir ;; esac diff --git a/lib/show.sh b/lib/show.sh index 4ed5c65..91fe17d 100644 --- a/lib/show.sh +++ b/lib/show.sh @@ -148,6 +148,30 @@ _u7_show() { esac ;; + ports) + case "$1" in + match) + if [[ -z "$2" ]]; then + echo "Usage: u7 sh ports match " + return 1 + fi + if command -v ss &>/dev/null; then + ss -tlnp | grep -i "$2" + else + netstat -tlnp 2>/dev/null | grep -i "$2" + fi + ;; + "") + if command -v ss &>/dev/null; then + ss -tlnp + else + netstat -tlnp 2>/dev/null + fi + ;; + *) echo "Usage: u7 sh ports [match ]" ; return 1 ;; + esac + ;; + port) lsof -i tcp:"$1" ;; diff --git a/test.sh b/test.sh index a0fcda4..a25db32 100755 --- a/test.sh +++ b/test.sh @@ -951,6 +951,40 @@ assert_contains "sh system shows uptime" "Uptime:" "$result" assert_contains "sh system shows shell" "Shell:" "$result" assert_contains "sh system shows user" "User:" "$result" +# Test: sh ports lists listening ports +if command -v ss &>/dev/null || command -v netstat &>/dev/null; then + result=$(u7 sh ports 2>&1) + if [[ $? -eq 0 ]]; then + echo -e "${GREEN}✓${NC} sh ports runs without error" + ((PASSED++)) + else + echo -e "${RED}✗${NC} sh ports runs without error" + echo " Got: $result" + ((FAILED++)) + fi +else + echo -e "${GREEN}✓${NC} sh ports runs without error (skipped - ss/netstat not installed)" + ((PASSED++)) +fi + +# Test: sh ports shows usage on invalid arg +result=$(u7 sh ports badarg 2>&1) +assert_contains "sh ports rejects invalid arg" "Usage:" "$result" + +# Test: sh ports match requires pattern +result=$(u7 sh ports match 2>&1) +assert_contains "sh ports match requires pattern" "Usage:" "$result" + +# Test: sh ports match filters output (may return nothing, just check it runs) +if command -v ss &>/dev/null || command -v netstat &>/dev/null; then + u7 sh ports match ssh 2>&1 + echo -e "${GREEN}✓${NC} sh ports match runs without crash" + ((PASSED++)) +else + echo -e "${GREEN}✓${NC} sh ports match runs without crash (skipped - ss/netstat not installed)" + ((PASSED++)) +fi + # Cleanup cd / rm -rf "$TEST_DIR"