Files
dotfiles/local/bin/x-localip

130 lines
3.5 KiB
Bash
Executable File

#!/bin/bash
#
# x-localip: script to display the local IP addresses of the system
#
# Author: Ismo Vuorinen <https://github.com/ivuorinen>
# 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