Created
November 13, 2025 13:10
-
-
Save larsyencken/2cc0a78693c5a0675d411842a21805d2 to your computer and use it in GitHub Desktop.
Nushell: helper to list all ports on MacOS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # List all well-known services and their port numbers. | |
| def "services" []: nothing -> table { | |
| open --raw /etc/services | |
| | lines | |
| | where {|l| not ($l =~ '^#')} | |
| | split column --regex '\s+' | |
| | select column1 column2 | |
| | rename name port | |
| | update port {|r| $r.port | split row '/' | get 0 | into int} | |
| | sort-by port | |
| | uniq | |
| } | |
| def "ports raw" [ | |
| --all | |
| ]: nothing -> string { | |
| if $all { | |
| sudo lsof -nP -iTCP -sTCP:LISTEN -iUDP | |
| } else { | |
| lsof -nP -iTCP -sTCP:LISTEN -iUDP | |
| } | |
| } | |
| # List all open ports and their services. | |
| def "ports" [ | |
| --all | |
| --proto: string = "tcp" # "tcp", "udp" or "all" | |
| ]: nothing -> table { | |
| let results = if $all { | |
| ports raw --all | |
| } else { | |
| ports raw | |
| } | |
| | str replace '[::1]' 'localhost' | |
| | detect columns --guess | |
| | where NAME =~ LISTEN or NODE == 'UDP' # include all listening connections | |
| | where NODE != 'UDP' or NAME !~ "->" # ignore UDP connections that are not listening | |
| | select COMMAND PID USER NODE NAME | |
| | sort-by COMMAND | |
| | uniq | |
| | update NODE {|row| $row.NODE | str downcase} # lowercase protocol | |
| | rename command pid user node bind_port | |
| | update bind_port {|row| $row.bind_port | str replace '[::1]' '127.0.0.1'} | |
| | update bind_port {|row| $row.bind_port | split row ' ' | get 0 | split row ':' } | |
| | insert interface {|r| $r.bind_port | get 0} | insert port {|r| $r.bind_port | get 1} | |
| | reject bind_port | |
| | rename -c {port: port_name, node: protocol} | |
| | join --left (services | rename -c {name: port_name}) port_name | |
| | update port {|r| $r.port | default $r.port_name } | |
| | insert maybe_port_int {|r| if ($r.port == '*') { "0" } else { $r.port } | into int } | |
| | reject port_name | |
| | sort-by maybe_port_int | |
| | reject maybe_port_int | |
| if $proto == "all" { | |
| $results | |
| } else { | |
| $results | where protocol == $proto | reject protocol | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment