3

I need to run console command in ruby (in my case to start Gvim), get PID of Gvim and kill that process in a few seconds.

If I do the following - it gives me PID of parent process, but I need somehow to find out the PID of Gvim.

IO.popen("gvim file_name_to_open" { |gvim|
  puts gvim.pid
}

If I do the following, it just starts Gvim and does nothing more (I need Gvim process to be killed).

pid = Process.spawn("gvim", "file_name_to_open")
sleep(5)
Process.kill(9, pid)
Process.wait pid

What am I doing wrong?

kovpack
  • 4,905
  • 8
  • 38
  • 55
  • Why are you trying to kill a process immediately after starting it? – mrosales Dec 04 '14 at 21:50
  • 2
    Also, the second example works fine for me, except I changed `5.seconds` to just `5` (since `.seconds` is not built in) – mrosales Dec 04 '14 at 21:50
  • Sorry, there was something else that I missed - I was using vim instead of gvim. At least on my system, gvim is just a function that spawns a process and returns immediately. This means that the pid you are getting from spawning gvim is not the actual pid of the gvim process, but rather the one of an intermediate process. – mrosales Dec 04 '14 at 21:58
  • Yes, I corrected - `seconds` was a mistake, now parent process is killed properly, but anyway I still can not get PID of Gvim, cause it is, actually, started by spawned process as other process. Any other ideas? – kovpack Dec 04 '14 at 22:10
  • I'm not sure. You should look into what your gvim command actually does (maybe try looking at your gvim file and seeing what it does). Mine launches a MacVim process and then forks it to have another vim instance. You can see the pid and kill the process manually with something like `ps -x | grep -i vim` but I am not sure how to find the pid without using `ps` – mrosales Dec 04 '14 at 23:26
  • Yes, I'm already thinking about finding gvim and just killing it, but that will kill all gvim processes (I can have multiple vims :) ). That is the problem :) – kovpack Dec 04 '14 at 23:29
  • sorry, I am out of ideas :( – mrosales Dec 04 '14 at 23:36
  • I think I've found quite a hacky solution. Actually, it's not a problem to run other command like `pidof gvim`. That will return list of PIDs. And it turned out that those PIDs look like a stack. The last one in the list - is the oldest gvim. Maybe, I'll just get the first one from this list (newest one) and kill it. Can't think of better ideas. For my task that can be sufficient, I suppose. – kovpack Dec 04 '14 at 23:43

1 Answers1

1

The most appropriate solution looks like this:

parent_pid = Process.spawn("gvim", "file_name_to_open")
# Need to wait in order not to kill process till Gvim is started and visible
sleep(5)  
Process.kill(9, parent_pid)
# Try to get all Gvim PIDs: the result will look like list of PIDs in 
# descending order, so the first one is the last Gvim opened.
all_gvim_pids = `pidof gvim` 
last_gvim_pid = all_gvim_pids.split(' ').map(&:to_i).first
Process.kill(9, last_gvim_pid)

The solution is strange and hacky, but noone has better ideas :(

kovpack
  • 4,905
  • 8
  • 38
  • 55