0

I am trying to create my first bash script. The goal of this script is to check at what rate my public IP changes. It is a fairly straight forward script. First it checks if the new address is different from the old one. If so then it should update the old one to the new one and print out the date along with the new IP address.

At this point I have created a simple script in order to accomplish this. But I have two main problems.

First the script keeps on printing out the IP even tough it hasn't changed and I have updated the PREV_IP with the CUR_IP.

My second problem is that I want the output to direct to a file instead of outputting it into the terminal.

The interval is currently set to 1 second for test purposes. This will change to a higher interval in the final product.

#!/bin/bash  
while true  
PREV_IP=00
do  
        CUR_IP=$(curl https://ipinfo.io/ip)
        if [ $PREV_IP != "$CUR_IP" ]; then
        PREV_IP=$CUR_IP
        "$(date)" 
        echo "$CUR_IP"
        sleep 1
        fi
done

I also get a really weird output. I have edited my public IP to xx.xxx.xxx.xxx:

Sat 20 Mar 09:45:29 CET 2021
xx.xxx.xxx.xxx
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:-- 
Stephen
  • 913
  • 3
  • 24
  • 50
  • Please paste your script first at [shellcheck.net](http://www.shellcheck.net/) and try to implement the recommendations made there. – Cyrus Mar 20 '21 at 09:09
  • Btw.: `sh` ([Bourne-shell](https://en.wikipedia.org/wiki/Bourne_shell)) is usally not `bash` ([Bourne-again shell](https://en.wikipedia.org/wiki/Bash_(Unix_shell))). – Cyrus Mar 20 '21 at 09:10
  • I have updated it to bin/bash. I will check the spellchecker! – Stephen Mar 20 '21 at 09:12
  • When you say "get a really weird output", what do you mean exactly? – Chris J Mar 20 '21 at 09:15
  • The output should just be `Sat 20 Mar 09:45:29 CET 2021 xx.xxx.xxx.xxx` and not all the other output I have put inside the code block in the question. – Stephen Mar 20 '21 at 09:19
  • 1
    Tip: `curl -s`. – tadman Mar 20 '21 at 09:22

1 Answers1

1
while true  
PREV_IP=00
do

is the reason you are seeing ip each loop. It's the same as while true; PREV_IP=00; do. The exit status of true; PREV_IP=00 is the exit status of last command - the exit status of assignment is 0 (success) - so the loop will always execute. But PREV_IP will be reset to 00 each loop... This is a typo and you meant to set prev_ip once, before the loop starts.

    "$(date)" 

will try execute the output of date command, as a next command. So it will print:

$ "$(date)" 
bash: sob, 20 mar 2021, 10:57:02 CET: command not found

And finally, to silence curl, read man curl first and then find out about -s. I use -sS so errors are also visible.

Do not use uppercase variables in your scripts. Prefer lower case variables. Check you scripts with http://shellcheck.net . Quote variable expansions.

I would sleep each loop. Your script could look like this:

#!/bin/bash
prev=""
while true; do  
        cur=$(curl -sS https://ipinfo.io/ip)
        if [ "$prev" != "$cur" ]; then
            prev="$cur"
            echo "$(date) $cur"
        fi
        sleep 1
done

that I want the output to direct to a file instead of outputting it into the terminal.

Then research how redirection works in shell and how to use it. The simplest would be to redirect echo output.

 echo "$(date) $cur" >> "a_file.txt"

The interval is currently set to 1 second for test purposes. This will change to a higher interval in the final product.

You are still limited with the time it takes to connect to https://ipinfo.io/ip. And from ipinfo.io documentation:

Free usage of our API is limited to 50,000 API requests per month.

And finally, I wrote a script where I tried to use many public services as I found ,get_ip_external for getting external ip address. You may take multiple public services for getting ipv4 address and choose a random/round-robin one so that rate-limiting don't kick that fast.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • How would I be able to execute and run your script inside my own script? I have tried sh ./find_ip.sh. But it throws an error "find_ip.sh: 2: set: Illegal option -o pipefail" – Stephen Mar 20 '21 at 11:29
  • 1. Install bash. 2. Run the script with bash, not sh. Did you try [google the error](https://stackoverflow.com/questions/54055549/linux-ubuntu-set-illegal-option-o-pipefail)? – KamilCuk Mar 20 '21 at 11:30