Search code examples
linuxbashfunction

Bash: Trying to get public IPv6 through a function


I am trying to see if my public IPv6 have anything in it, if not then output the text Unknown in a variable (for storage). Then have the variable shown later in a text eg: echo "Public IPv6: "$PIP6 (variable that to save).

I know that I don't have a public IPv6 (it is slow to come in my country), so I would expect it to say Unknown. But it is empty.

What seems to be the problem?

test.sh

#!/bin/bash
OS="$(uname)"
InternalIP=""
LIP="ip addr show"
LIP6="ip -6 addr show scope global"
IPv6=""
PIPv6=""

case $OS in
 *)InternalIP=$($LIP | grep 'inet'| grep -v '127.0.0.1' | cut -d: -f2 | awk 'NF>0{print $2}');;
esac
case $OS in
 *)IPv6=$($LIP | grep 'inet6' | grep -v '128' | awk '{print $2}');;
esac
case $OS in
 *)PIPv6=$($LIP6 | grep 'inet6' | grep -v '128' | awk '{print $2}');;
esac
   if [ -z $PIPv6 ]; then
    echo $PIPv6
   else
    echo "Unknown"
   fi

length=$InternalIP
echo $InternalIP | awk '{print substr($0, 1, length($0)-3)}'
echo $IPv6 | awk '{print substr($0, 1, length($0)-3)}'
echo "Public IPv6: "$PIPv6

I tried different if styles. tried with echo "Unknown instead of result and then it showed up as Unknown, but I want it to save to a variable, not showing up at the beginning of the output:

Unknown
1xx.xxx.xxx.xxx
xxxx::xxxx:xxxx:xxxx:xxx
Public IPv6: 

Now when I run the file: publicip.sh

#!/bin/bash
LIB="ip address show" # Show Network Information
PIB6="ip -6 adress show scope global" # Public IPv6

IPv4="$($LIB | awk '/inet/ && !/127/ && !/128/ && !/64/{print $2}')"
IPv6="$($LIB | awk '/inet6/ && !/128/{print $2}')"
PIPv4="$(dig +short myip.opendns.com @resolver1.opendns.com)"
PIPv6="$($PIP6 | awk '/inet6/ && !/128/{print $2}')"

if [ -z "$PIPv6" ]; then
  PIPv6="unknown"
fi

echo "Local IPv4: $IPv4" | awk '{print substr($0,1,length($0)-3)}'
echo "Local IPv6: $IPv6" | awk '{print substr($0,1,length($0)-3)}'
echo "Public IPv4: $PIPv4"
echo "Public IPv6: $PIPv6"

Output:

Local IPv4: xxx.xxx.xxx.xxx
Local IPv6: xxxx::xxxx:xxxx:xxxx:xxx
Public IPv4: xxx.xxx.xxx.xxx
Public IPv6: Unknown

Just like I want it.


Solution

  • Try this, untested:

    #!/usr/bin/env bash
    
    InternalIP=""
    lip() { ip addr show; }
    lip6() { ip -6 addr show scope global; }
    IPv6=""
    PIPv6=""
    
    InternalIP=$(lip | awk -F':' '/inet/ && !/127\.0\.0\.1/ && split($2,a," ")>1{print a[2]}')
    IPv6=$(lip | awk '/inet6/ && !/128/{print $2}')
    PIPv6=$(lip6 | awk '/inet6/ && !/128/{print $2}')
    
    if [[ -z $PIPv6 ]]; then
        PIPv6='Unknown'
    fi
    
    echo "$InternalIP" | awk '{print substr($0, 1, length($0)-3)}'
    echo "$IPv6" | awk '{print substr($0, 1, length($0)-3)}'
    echo "Public IPv6: $PIPv6"
    

    I don't understand some of your code and you didn't provide the output of your 2 ip commands so I don't know why you're using the commands you are on it so the above is just a translation of your code into what I think you wanted it to do.

    The most significant change is probably that I think you wanted to set PIPv6 to Unknown when it's empty, not just print a blank line.