#!/usr/bin/env bash set -euo pipefail # Script Name: myip # Description: Show external and internal IP addresses with optional features # Usage: myip # Show all IPs # myip -e # External IP only # myip -i # Internal IPs only # myip -c # Copy external IP to clipboard # myip -j # JSON output # myip -a # All info (IPs + gateway + DNS) VERSION="1.0.0" # Colors readonly RED='\033[0;31m' readonly GREEN='\033[0;32m' readonly YELLOW='\033[1;33m' readonly BLUE='\033[0;34m' readonly CYAN='\033[0;36m' readonly MAGENTA='\033[0;35m' readonly BOLD='\033[1m' readonly NC='\033[0m' show_help() { echo -e "${BOLD}myip${NC} - IP Address Information Tool v${VERSION}" echo echo -e "${BOLD}USAGE:${NC}" echo " myip [OPTIONS]" echo echo -e "${BOLD}OPTIONS:${NC}" echo -e " ${CYAN}-e, --external${NC} Show external IP only" echo -e " ${CYAN}-i, --internal${NC} Show internal IPs only" echo -e " ${CYAN}-c, --copy${NC} Copy external IP to clipboard" echo -e " ${CYAN}-j, --json${NC} Output as JSON" echo -e " ${CYAN}-a, --all${NC} Show all network info (IPs + gateway + DNS)" echo -e " ${CYAN}-h, --help${NC} Show this help message" echo echo -e "${BOLD}EXAMPLES:${NC}" echo " myip # Show both external and internal IPs" echo " myip -e # External IP only" echo " myip -c # Copy external IP to clipboard" echo " myip -j # JSON format for scripting" echo " myip -a # Complete network information" echo echo -e "${BOLD}OUTPUT:${NC}" echo " External IP, Internal IPs, Gateway (with -a), DNS servers (with -a)" } # Get external IP with fallback sources get_external_ip() { local ip="" # Try multiple sources for reliability sources=( "https://ifconfig.me" "https://api.ipify.org" "https://icanhazip.com" "https://checkip.amazonaws.com" ) for source in "${sources[@]}"; do ip=$(curl -sf --max-time 3 "$source" 2>/dev/null | tr -d '[:space:]') if [[ -n "$ip" ]] && [[ "$ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo "$ip" return 0 fi done echo "unable to fetch" >&2 return 1 } # Get internal IPs get_internal_ips() { if command -v ip &>/dev/null; then # Modern Linux ip -4 addr show | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v '127.0.0.1' elif command -v ifconfig &>/dev/null; then # macOS / older Linux ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1' else echo "No network tools found" >&2 return 1 fi } # Get internal IPs with interface names get_internal_ips_detailed() { if command -v ip &>/dev/null; then ip -4 addr show | awk ' /^[0-9]+:/ { iface = $2; gsub(/:/, "", iface) } /inet / && !/127\.0\.0\.1/ { split($2, a, "/") print iface ":" a[1] } ' elif command -v ifconfig &>/dev/null; then ifconfig | awk ' /^[a-z]/ { iface = $1; gsub(/:/, "", iface) } /inet / && !/127\.0\.0\.1/ { for (i=1; i<=NF; i++) { if ($i == "inet") { print iface ":" $(i+1) break } } } ' fi } # Get default gateway get_gateway() { if command -v ip &>/dev/null; then ip route | grep default | awk '{print $3}' | head -1 elif command -v route &>/dev/null; then route -n | grep '^0.0.0.0' | awk '{print $2}' | head -1 elif command -v netstat &>/dev/null; then netstat -rn | grep default | awk '{print $2}' | head -1 else echo "unknown" fi } # Get DNS servers get_dns_servers() { if [[ -f /etc/resolv.conf ]]; then grep nameserver /etc/resolv.conf | awk '{print $2}' | tr '\n' ' ' else echo "unknown" fi } # JSON output json_output() { local external_ip=$(get_external_ip || echo "unknown") local internal_ips=$(get_internal_ips | tr '\n' ',' | sed 's/,$//') local gateway=$(get_gateway) local dns=$(get_dns_servers) cat << EOF { "external_ip": "$external_ip", "internal_ips": [$( echo "$internal_ips" | sed 's/,/","/g; s/^/"/; s/$/"/' )], "gateway": "$gateway", "dns_servers": [$( echo "$dns" | sed 's/ /","/g; s/^/"/; s/$/"/' )] } EOF } # Colorized output colorized_output() { local show_external=${1:-true} local show_internal=${2:-true} local show_all=${3:-false} if [[ "$show_external" == "true" ]]; then echo -e "${BOLD}${CYAN}External IP:${NC}" external_ip=$(get_external_ip || echo "${RED}Unable to fetch${NC}") echo -e " ${GREEN}$external_ip${NC}" echo fi if [[ "$show_internal" == "true" ]]; then echo -e "${BOLD}${CYAN}Internal IPs:${NC}" while IFS=: read -r iface ip; do echo -e " ${YELLOW}$iface${NC}: ${GREEN}$ip${NC}" done < <(get_internal_ips_detailed) echo fi if [[ "$show_all" == "true" ]]; then echo -e "${BOLD}${CYAN}Gateway:${NC}" echo -e " ${GREEN}$(get_gateway)${NC}" echo echo -e "${BOLD}${CYAN}DNS Servers:${NC}" for dns in $(get_dns_servers); do echo -e " ${GREEN}$dns${NC}" done echo fi } # Parse arguments mode="default" show_external=true show_internal=true show_all=false copy_to_clipboard=false json_format=false while [[ $# -gt 0 ]]; do case $1 in -e|--external) show_external=true show_internal=false shift ;; -i|--internal) show_external=false show_internal=true shift ;; -c|--copy) copy_to_clipboard=true shift ;; -j|--json) json_format=true shift ;; -a|--all) show_all=true shift ;; -h|--help) show_help exit 0 ;; *) echo "${RED}Error: Unknown option: $1${NC}" >&2 echo "Run 'myip --help' for usage information" >&2 exit 1 ;; esac done # Clipboard helper clip_set() { if command -v xsel &>/dev/null; then xsel --input --clipboard elif command -v xclip &>/dev/null; then xclip -selection clipboard fi } # Main logic if [[ "$json_format" == "true" ]]; then json_output elif [[ "$copy_to_clipboard" == "true" ]]; then external_ip=$(get_external_ip) echo -n "$external_ip" | clip_set echo -e "${GREEN}✓${NC} Copied to clipboard: ${BOLD}$external_ip${NC}" else colorized_output "$show_external" "$show_internal" "$show_all" fi