1

I am trying to write the output of top to a file every 5 seconds which I also got to work.

cmd = "top -s 5 -pid 123 >> top.txt"
p = IO.popen(cmd)

However, the problem I have is that I can't find a way of closing top I have tried

Process.kill('KILL', p.pid)

but top keeps writing to the output file. p.close hangs but if I ctrl + c it does seem to exit the top command as well. But this as this requires me to manually ctrl + c it is not a viable solution.

Any help would be appreciated!

Max
  • 21,123
  • 5
  • 49
  • 71

1 Answers1

3

The problem is the redirection. >> is a feature of a shell: it starts the process and connects its stdout to the given file. In order for Ruby to do this, it actually starts a shell, which starts top and sets up the redirection.

So p.pid is the PID of the shell, not top. When you kill it, it kills only the shell and top gets disowned, continuing to run under PID 1.

I recommend using Popen3 instead and running just top -s 5 -pid 123 without redirection. This gives you the subprocess as well as its stdout/stderr, so you can manage the output yourself (such as appending it to a file) while being able to kill it.

Alternatively, make a wrapper shell script that runs top with redirection and set it up to kill top when it exits: How do I terminate all the subshell processes? Then have Ruby run that wrapper script.

Max
  • 21,123
  • 5
  • 49
  • 71
  • Hi, thank you for you answer. I thought something like that might have happened. Really stupid question but if I were to use something like `cmd = top -s 5 -pid 123` & `stdin, stdout, stderr, wait_thr = Open3.popen3(cmd)` how would I then write the output to my file? And would to output of `cmd` be saved in memory? – John Stevenson Mar 17 '21 at 08:45
  • 1
    you can loop on `stdout.gets` and `puts` that to a file opened in `a` (append) mode. If you want to do that in the background while your script continues you can do it in a `Thread`. If you're more comfortable with shell scripting I recommend making the wrapper shell script as suggested at the end of my answer – Max Mar 17 '21 at 13:28