diff --git a/local/bin/x-localip b/local/bin/x-localip new file mode 100755 index 0000000..2e5fc7b --- /dev/null +++ b/local/bin/x-localip @@ -0,0 +1,128 @@ +#!/bin/bash +# +# x-localip: script to display the local IP addresses of the system +# +# Author: Ismo Vuorinen +# License: MIT + +VERSION="1.0.0" + +# Function to display usage +usage() +{ + echo "Usage: x-localip [options] [interface]" + echo "Options:" + echo " --help Show this help message" + echo " --version Show version information" + echo " --ipv4 Show only IPv4 addresses" + echo " --ipv6 Show only IPv6 addresses" + echo "If an interface is specified, only the IP address of that interface will be returned." +} + +# Initialize flags for filtering +show_ipv4=true +show_ipv6=true + +# Check for arguments +while [[ $# -gt 0 ]]; do + case $1 in + --help) + usage + exit 0 + ;; + --version) + echo "x-localip version $VERSION" + exit 0 + ;; + --ipv4) + show_ipv6=false + ;; + --ipv6) + show_ipv4=false + ;; + *) + iface=$1 + ;; + esac + shift +done + +declare -a interfaces + +# Detect platform (macOS or Linux) +platform="$(uname)" +if [[ $platform == "Darwin" ]]; then + read -r -a interfaces <<< "$(ifconfig -lu | grep -v '^bridge')" +elif [[ $platform == "Linux" ]]; then + read -r -a interfaces <<< "$(ip link show | awk -F: '/^[0-9]+:/{print $2}' | tr -d ' ' | grep -v '^bridge')" +else + echo "Error: Unsupported platform. Only macOS and Linux are supported." + exit 1 +fi + +# Function to fetch IP addresses for an interface +fetch_ips() +{ + iface="$1" + local ipv4 ipv6 + if [[ $platform == "Darwin" ]]; then + ipv4=$(ipconfig getifaddr "$iface" 2> /dev/null || echo "") + ipv6=$(ipconfig getifaddr -v6 "$iface" 2> /dev/null || echo "") + else + ipv4=$(ip -4 addr show "$iface" 2> /dev/null | awk '/inet / {print $2}' || echo "") + ipv6=$(ip -6 addr show "$iface" 2> /dev/null | awk '/inet6 / {print $2}' || echo "") + fi + if [[ -n $ipv4 || -n $ipv6 ]]; then + echo "$iface:$ipv4:$ipv6" + fi +} + +# Determine maximum lengths for formatting +max_iface_length=9 # "Interface" length +max_ipv4_length=11 # "IPv4 Address" length +max_ipv6_length=11 # "IPv6 Address" length + +interface_ip_list=() +for iface in "${interfaces[@]}"; do + result=$(fetch_ips "$iface") + if [[ -n $result ]]; then + interface_ip_list+=("$result") + fi +done + +interface_ip_list_array=() +for entry in "${interface_ip_list[@]}"; do + IFS=: read -r iface ipv4 ipv6 <<< "$entry" + [[ ${#iface} -gt $max_iface_length ]] && max_iface_length=${#iface} + [[ ${#ipv4} -gt $max_ipv4_length ]] && max_ipv4_length=${#ipv4} + [[ ${#ipv6} -gt $max_ipv6_length ]] && max_ipv6_length=${#ipv6} + interface_ip_list_array+=("$iface:$ipv4:$ipv6") +done + +# Print headers +printf "%-${max_iface_length}s : %-${max_ipv4_length}s : %-${max_ipv6_length}s\n" "Interface" "IPv4 Address" "IPv6 Address" +printf "%0.s-" $(seq 1 $((max_iface_length + max_ipv4_length + max_ipv6_length + 6))) +printf "\n" + +# Print the results in a formatted table +for entry in "${interface_ip_list_array[@]}"; do + # Split the entry into interface, IPv4, and IPv6 + iface="${entry%%:*}" + rest="${entry#*:}" + ipv4="${rest%%:*}" + ipv6="${rest#*:}" + + # Skip IPv4 or IPv6 as per the flags + ipv4_display=$([[ $show_ipv4 == true ]] && echo "$ipv4" || echo "") + ipv6_display=$([[ $show_ipv6 == true ]] && echo "$ipv6" || echo "") + + # Print the interface name, padded to max_iface_length, followed by the IPs + printf "%-${max_iface_length}s" "$iface" + if $show_ipv4; then + printf " : %-${max_ipv4_length}s" "$ipv4_display" + fi + if $show_ipv6; then + printf " : %-${max_ipv6_length}s" "$ipv6_display" + fi + printf "\n" +done