1

I’ve got a question for you that is theoretical.

While running a process in the terminal I often just care about the most recent last line. And I want to call the data in that line from another program.

So, consider I want to build something like a ping server. This ping server will write the most recent line of ping to a text file. And this file can be read without any corruption.

So to start, I would do something simple like

ping 8.8.8.8 > ping.txt

But that is going to write each line to the file. I just want a file with the most recent ping.

Now, if I get to this point. I will have trouble reading the file at times because it is being written to as well. How do I avoid this issue?

5
  • tail comes to mind. See man tail
    – Elder Geek
    Feb 28, 2017 at 20:41
  • But I don't want to record all of the pings. I just want to write one ping.
    – cylondude
    Feb 28, 2017 at 20:42
  • See my answer..
    – Elder Geek
    Feb 28, 2017 at 20:46
  • 1
    This is an XY problem. Calling it theoretical doesn't change that. What is it you really aim to accomplish with this that you cannot do by simply reading the last line?
    – muru
    Mar 1, 2017 at 4:41
  • I'm open to any kind of solution to the title of the problem. It does not have to be ping. Ping is a good example I believe because it is consistently writing new data in a manageable and testable way. The root of the question does not have to do with XY.
    – cylondude
    Mar 1, 2017 at 5:58

1 Answer 1

1

Here are some practical answers to your "theoretical" question.

tail can do this for you

Example:

ping -c 10 8.8.8.8 | tail --lines=3 > output.file

the -c 10 switch in the ping command limits the pings to 10 rather than continuing indefinitely which is the default. the lines=3 switch in the tail command limits output to the last 3 lines which is what we really care about usually.

This will result in only the summary (last 3 lines) as shown below:

--- 8.8.8.8 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9014ms
rtt min/avg/max/mdev = 22.810/25.120/31.137/2.936 ms

If for some odd reason you truly want the output of a single ping just modify the above to ping -c 1 8.8.8.8 | head --lines=2 | tail --lines=1 > output.file

Resulting in:

64 bytes from 8.8.8.8: icmp_seq=1 ttl=45 time=24.0 ms

Edit: Continuous single ping As requested in comment:

while :; do ping -c 1 8.8.8.8>output.file; sleep 1; done

Since while : always evaluates as true this will loop indefinitely, running ping and redirecting the output to output.file, overwriting it each time the loop runs. It pauses for a second with each iteration in order to allow you time to read the output.

You can experiment with sleep values below a second such as 0.5 or 0.01 but at some point you will have too short a delay between writes and be back where you started.

Sources:

man ping

man tail

Experience

https://www.cyberciti.biz/faq/bash-infinite-loop/

http://www.linuxforums.org/forum/programming-scripting/70966-possible-sleep-less-than-1-sec-simple-bash-script.html

5
  • While your example is running I can't call any of the lines it is writing. The point of my question is to let ping run indefinitely and read the most recent request. Not just print the last line.
    – cylondude
    Mar 1, 2017 at 6:00
  • While I honestly don't see the value of this it's still relatively simple. See my updated answer
    – Elder Geek
    Mar 1, 2017 at 14:31
  • 1
    Please keep an open mind and remember that just because an answer isn't the one you wanted doesn't mean it's wrong. I suggest that you review The final paragraph here
    – Elder Geek
    Mar 1, 2017 at 14:49
  • but your revised answer is exactly what I was looking for from the start. Thank you.
    – cylondude
    Mar 3, 2017 at 5:58
  • @cylondude I'm glad we got it sorted to your satisfaction!
    – Elder Geek
    Mar 3, 2017 at 21:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .