55

I want to write the output of a specific 'top' command to a file. I did some googling and find out that it can be done by using the following command.

top -n 10 -b > top-output.txt

where -n is to specify the number of iterations and -b is for batch mode. This works very well if let top for the 10 iterations. But if i break the running of the command with a Ctrl-C, the output file seems to be empty.

I won't be knowing the number of iterations beforehand, so i need to break it manually. How can i capture the output of top in a file without specifying iterations?

The command which I am trying to use precisely is

top -b | grep init > top-output.txt

and break it whenever i want. But it doesn't work.

EDIT: To give more context to the question, I have a Java Code which invokes a tool with an Input File. As in the tool takes a file as an input and runs for some time, then takes the next file and so on. I have a set of 100,000 files which need to be fed to the tool. So now I am trying to monitor that specific tool ( It runs as a process in Linux). I cannot capture the whole of 'top' s data as the file as would be too huge with unwanted data. How to capture the system stats of just that process and write it to a file using top?

6
  • what stats do you want? do you know about "time"? Commented Jul 30, 2012 at 22:00
  • i want the %CPU and %MEM usage stats. I dont think 'time' will help me get those. Commented Jul 30, 2012 at 22:02
  • time will give you wall clock time and processor time in the end so you can calculate cpu% average. how about finding out the PID of the tool and running "ps" for that PID repeatedly? Commented Jul 30, 2012 at 22:06
  • That wont work as the tool constantly gets closed and reopens again. So different PID everytime. Would be great if i can track using the name of the tool. Commented Jul 30, 2012 at 22:12
  • Oh that could work. I am not familiar with ps in linux. When i do a ps i just get the 'time', how do you get other details like CPU and MEM in ps ? I looked at the man page but that doesnt seem to help either. Commented Jul 30, 2012 at 22:25

11 Answers 11

52

for me top -b > test.txt will store all output from top ok even if i break it with ctrl-c. I suggest you dump first, and then grep the resulting file.

Sign up to request clarification or add additional context in comments.

12 Comments

this way you can also follow the file as it grows using less or tail -f
Be aware that the -b flag is specfic to the GNU version of top. That's fine on most linux systems but may not be portable to busybox based systems or other unixs.
he used -b flag so i assume it is available
@dmckee Ya man noted. In fact i tried to solve the same problem in Mac OSX with a -b but it didnt work. Found out that top has no batch mode in OSX.
i think your problem might be caused by maybe grep stripping line feeds from your output and then the buffering will eat all output until buffer runs out or there is an end of stream. Just a guess.
|
17

How about using while loop and -n 1:

while sleep 3; do 
  top -b -n1 | grep init > top-output.txt
done

5 Comments

I will try this out. Coz the last time i tried a similar loop, top stopped capturing the process once it went out the list and didnt start to recapture when the proces came back to the list. Ill try it out and let you know.
@Pradep, I think the reason it stopped is that while will stop if the last command in the while condition fails. This is why Thor has used while :;. : is a special command that always succeeds. I assume you did while top ...; do ...; done ?
Need >> to append. And can clear out when processed. this will have only the latest. which is fine if its processed when done
I personally discourage the use of the first top iteration, as it lacks proper reference for its averages, afaik. See this thread
The loop would work with a primitive version of top but not needed for GNU top. Using a loop with -n 1 defeats the purpose of -n and simply piping the output of top -b to a file would suffice. The sleep can be replaced with -d to set up a different update interval.
5

CTRL+C is not a ideal solution due to control stays in CLI. You can use below command which dumps top output to a file:

top -n 1 -b > top-output.txt

Comments

4

It looks like the output is not writing to the file until all iterations are finished. You could solve this by wrapping with an external loop like this:

touch top-output.txt
while true; do
    top -b | grep init >> top-output.txt
done

8 Comments

atleast on my linux machine it writes it as a stream to the stdout, so the output file is updated real time.
Try it now, I realized that I had set the initial value of x incorrectly so that the loop would never be executed.
I am new to all this. Could you tell me how to stop this from running ? I tried Ctrl-c . But that doesnt work here. :)
I have edited to a version which will run until you press Ctrl-c.
Still doesnt close on Ctrl-C . Ctrl - Z worked though. I dunno if its expected.
|
3

Here is the 1-liner I like to use on my mac:

top -o -pid -l 1 | grep "some regexp"

Cheers.

Comments

2

Solved this issue. This works even if you press Ctrl+c Even I was facing the same issue when I wanted to log Cpu%. Execute this shell script:

#!/bin/sh
while true; do
    echo "$(top -b -n 1 | grep init)"  | tee -a top-output.log
    sleep 1
done
  • You can grep anything you wanna extract out of top command, use this script to store it to a file.
  • -b : Batch mode operation Starts top in Batch mode, which could be useful for sending output from top to other programs or to a file. In this mode, top will not accept input and runs until the iterations limit you've set with the -n command-line option or until killed.
  • -n number, this option specifies the maximum number of iterations, or frames, top should produce before ending. Here I've used -n 1.
  • Do man top for more details
  • tee -a enables the output to be visible on the console and also stores the output onto the file. -a option appends the output to the file.
  • Here, I have given an interval of 1 second. You can mention any other interval.

Source for explanations of -b and -n: manpages

man top

Kruthika

2 Comments

I personally discourage the use of the top's first iteration as it lacks a reference for its averages (see this comment).
2

As pointed out by @Thor in a comment, you just need to ensure that grep is not buffering arbitrarily but per-line with the --line-buffered option:

top -bn 10 | grep 'init' --line-buffered | tee top-output.txt

Without grep-ing, redirecting the output of top to a file works just fine, interrupt included.

Comments

1

If you wish to run the top command in background (just not to worry about logout/sleep, etc) - you can make use of nohup or batch job or cron or screen.

Using nohup (stands for : No Hang Up):

Say suppose if you save the top command in a file called top-exec.sh with following content :

 top -p <PID> -b > /tmp/top.log

You can replace the top command for whatever process you are interested in. Then, You can execute top-exec.sh using nohup as follows :

$> nohup top-exec.sh &

This will redirect all the output of top command to a file named "top.log".

Comments

0

I had the exact same problem...

here was my line:

top -b -u myUser | grep -v Prog.sh | grep Prog > myFile.txt

It would create myFile.txt but it would be empty when I Ctrl+C'd it. So after I kicked off my top command, then I started a SECOND top process. When I found the first top's PID (took some trial and error), and I killed it thru the second top, the first top wrote to the file as expected.

Hope that helps!

1 Comment

The reason for the missing output is that the middle grep will be buffered. Avoid this by running it like this: grep --line-buffered ...
0

Set the -n argument to 1 it tells top how many frames it will produce before exits.

top -b -n 1 > ~/mytopview.txt

or even

myvar=`top -b -n 1`
echo $myvar

Comments

-1

From the top command, we can see all the processes with their PID (Process ID). To print top output for only one process, use the following command:

$ top –p PID

To save top command of any process to a file, use the following command:

top -p $PROCESS_ID -b  > top.log

where > redirects standard output to a file.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.