0

I want to store the output of the terminal command top into a file, using Python. In the terminal, when I type top and hit enter, I get an output that is real time, so it keeps updating. I want to store this into a file for a fixed duration and then stop writing.

file=open("data.txt","w")
file.flush()
import os,time
os.system("top>>data.txt -n 1")
time.sleep(5)
exit()
file.close()

I have tried to use time.sleep() and then exit(), but it doesn't work, and the only way top can be stopped is in the terminal, by Control + C The process keeps running and the data is continuously written onto the file, which is not ideal, as one would guess

For clarity: I know how to write the output on to the file, I just want to stop writing after a period

Anubhav Dinkar
  • 343
  • 4
  • 16
  • Hello and welcome to StackOverflow. Please take some time to read the help page, especially the sections named ["What topics can I ask about here?"](http://stackoverflow.com/help/on-topic) and ["What types of questions should I avoid asking?"](http://stackoverflow.com/help/dont-ask). And more importantly, please read [the Stack Overflow question checklist](http://meta.stackexchange.com/q/156810/204922). You might also want to learn about [Minimal, Complete, and Verifiable Examples](http://stackoverflow.com/help/mcve). – bracco23 Jun 05 '19 at 07:18
  • 2
    Possible duplicate of [How do I redirect stdout to a file when using subprocess.call in python?](https://stackoverflow.com/questions/9347004/how-do-i-redirect-stdout-to-a-file-when-using-subprocess-call-in-python) – buran Jun 05 '19 at 07:19
  • cant you just run 'ps' with the options that gives you the information you need ? – Jimmy Engelbrecht Jun 05 '19 at 07:37

2 Answers2

2

system will wait for the end of the child process. If you do not want that, the Pythonic way is to directly use the subprocess module:

import subprocess

timeout=60   # let top run for one minute
file=open("data.txt","w")
top = subprocess.Popen(["top", "-n", 1], stdout=file)
if top.wait(timeout) is None:      # wait at most timeout seconds
    top.terminate()                # and terminate child

The panonoic way (which is highly recommended for robust code) would be to use the full path of top. I have not here, because it may depend on the actual system...

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
0

The issue you could be facing is that os.system starts the process as part of the current process. So the rest of your script will not be run until the command you run has completed execution.

I think what you want to be doing is executing your console command on another thread so that the thread running your python script can continue while the command runs in the background. See run a python program on a new thread for more info.

I'd suggest something like (this is untested):

import os
import time
import multiprocessing

myThread = multiprocessing.process(target=os.system,  args=("top>>data.txt -n 1",))
myThread.start()

time.sleep(5)
myThread.terminate()

That being said, you may need to consider the thread safety of os.system(), if it is not thread safe you'll need to find an alternative that is.

Something else worth noting (and that I know little about) is that it may not be ideal to terminate threads in this way, see some of the answers here: Is there any way to kill a Thread?

Henry
  • 54
  • 7