#!/bin/bash # # x-localip: script to display the local IP addresses of the system # # Author: Ismo Vuorinen # License: MIT VERSION="1.0.0" SCRIPT_NAME="$(basename "$0")" # Function to display usage usage() { echo "Usage: $SCRIPT_NAME [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 "$SCRIPT_NAME 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