2

I am running a small cli python app in terminal. It loops infinitely and outputs text to the terminal. I want to output the text to a file, and I can do that with the following command python [my cli app] >> log.txt, but I have to break the loop first before the file is closed and effectively saved. Is there a way to read the latest contents from the text file while the loop keeps running in the background?

SO BASICALLY:

~ $  [INFINITE LOOP] >> log.txt

then while thats running forever, I want to access log.txt. At the moment, it only saves the terminal output to the file once I stop the command with Ctrl+C.

I hope that explains it

  • I think you want tail -f log.txt but I'm not sure if I'm understanding the question right. – PSkocik Jul 22 '15 at 0:08
  • Problem is, tail only executes after you break the loop. I don't want to break the loop at all, or am I wrong? =/ And doesn't the tail command display existing text? I want to save text ^^ – John Kahts Jul 22 '15 at 0:09
  • 1
    That's not an answer. But you could write one. Understand, though, that you just effectively wrapped your program in its own pseudo-terminal - it's got its own byte-by-byte kernel buffer and stty line-editing interface and master-side monitor application and all of the other overhead which that entails. – mikeserv Jul 22 '15 at 0:48
  • 1
    real-talk, though: go google and find out how to adjust your write buffer with python. It must be possible. just that stdbuf didn't work is a pretty clear indication that python is doing some adjustments of its own at the the start anyway. Probably when you import some kind of file module or whatever you do in python. stdbuf works by injecting a c-lib call to set the out-buffer then execs your target app - so if the target app sets its own buffer later it was all for nought. – mikeserv Jul 22 '15 at 0:57
  • 1
    I will google it and maybe in a month's time I will know my away around Python ^^ I'm just a tiny C# programmer fiddling around in Python xD – John Kahts Jul 22 '15 at 1:00
1

simulation.py:

(output 10 lines every second)

#!/usr/bin/env python
import time

i=0
while True:
    print("{} what up {}".format(i,i%10))
    if i%10==9:
        time.sleep(1)
    i+=1

In one terminal:

$ stdbuf -oL python simulation.py >> log.txt

In another one:

$ tail -f log.txt #10 new lines every second
  • 1
    Thanks so much ^^ this works too now. I assume this is a more effective way what the luit command? Mike said to rather adjust the buffer than to run a seperate pseudo terminal thing – John Kahts Jul 22 '15 at 1:06
  • 1
    @JohnKahts - this is more efficient because it only needs to add a littlle logic at process init time and afterwards ceases to factor altogether. That can detract from its effectiveness in some cases, but, if it doesn't, then it does more with less, which is always the best way to do things (as I see it, anyway). By the way, I think you can get pretty specific about i/o buffer sizes with stdbuf, and so you might find a more conservative size which suits your needs. It would still be better though to find how to do it in your program - so you might adjust buffers dynamically to need. – mikeserv Jul 22 '15 at 1:26
  • @mikeserv - The amount of lines that are outputted is inconsistent, since it is dependant on the amount of queries I get from users. I understand that it would be better to incorporate the whole text file thing inside my code. So I shall try doing that as soon as I have the courage ;P Thanks again for your help sir =) – John Kahts Jul 23 '15 at 8:56
0

Working off PSkocik's answer:

instead of

$ stdbuf -oL python simulation.py >> log.txt

do

$ stdbuf -oL python simulation.py | tee log.txt

This way you'll be able to view the original output of the program as well on the same screen.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.