Search code examples
linuxshellpingtail

Linux shell - Output ping to file and only keep last X lines


I want to write a shell-Script for my Raspberry Pi to permanently ping a specific host but only keep the last 20 results in a text file.

So my idea was to redirect the ping output to a text file and write a loop to repeatedly limit said file to 20 lines:

ping ServerX.domain.com -i 5 -D 1>/home/user/Desktop/Ping.txt &
while :
do
    tail /home/user/Desktop/Ping.txt -n 20 >/home/user/Desktop/Ping.txt
done

This somehow keeps completely erasing the file content of Ping.txt? So I have to redirect the content to a variable and then rewrite it to the file:

ping ServerX.domain.com -i 5 -D >/home/user/Desktop/Ping.txt &
while :
do
    PingContent=$(tail /home/user/Desktop/Ping.txt -n 20)
    echo "$PingContent" >/home/user/Desktop/Ping.txt
    sleep 4
done

This seems to work quiet well, but every now and then some unreadable null-characters appear in the last line of my file. I guess this happens when both commands try to write into the Ping.txt at the same time. How may I avoid this?


Solution

  • So the problem is that the redirection > clears the target file before it starts tailing the content into it. And by the time it does, the file is already cleared.

    Here's my implementation how you might achieve the results(adjust as necessary):

    #!/bin/bash
    
    ping 127.0.0.1 -i 2 -D | while read pong; do 
        echo "$(tail -5 /tmp/pinglog.log)" > /tmp/pinglog.log
        echo "$(date):$pong" >> /tmp/pinglog.log  
    done;
    

    Here the evaluation in echo acts kind of like a "buffer".

    Sources: