3

I need to run a subprocess, execute some code, and then kill the started process; I don't need the output of this subprocess. I tried something like this:

def start
  @@rtorrentIO ||= IO.popen("rtorrent")
  sleep 0.5
end
def stop
  Process.kill(9, @@rtorrentIO.pid) if defined? @@rtorrentIO
  @@rtorrentIO = nil
end

start
sleep 0.5
#some code there
stop

but the terminal doesn't react to any actions that I did (even Ctrl+C escape). What am I doing wrong?

UPDATE: I was a little mistake in the initial conditions. In fact terminal react for all my actions but I don't see any symbols that I write before command executes. In the picture below I consistently execute the following commands: mangaParser.rb; whoami; ps; And that was I get to output: enter image description here

However, if i try to break runned command with Ctrl+C escape, it was failure (e.g. I can't break the following sequence of command without other terminal: mangaParser.rb; ping google.com;)

2
  • What do you get when you print @@torrentIO.pid before doing Process.kill? Commented Oct 4, 2014 at 16:40
  • @7stud Fixnum that represent process id of rtorrent, obviously :) I check it few times - it's really process id of runned subprocess. Commented Oct 5, 2014 at 2:40

1 Answer 1

1

If I change it to

#!/usr/bin/env ruby

def start
  @rtorrentIO ||= IO.popen("rtorrent",'w') #default mode is 'r'
  sleep 0.5
end
def stop
  Process.kill(9, @rtorrentIO.pid) if defined? @rtorrentIO
  @rtorrentIO = nil
end

start


sleep 0.5
#some code there
stop

to make it into a self-contained example, it works fine for me. You should probably open the pipe for writing (..,"w"), since you're uninterested in the output (and if you're not interested in writing into it, then there's no point in opening the process with popen and you're better off using things like pid = Process.spawn('rtorrent')).

UPDATE The problem you're experiencing is due to rtorrent messing up your terminal by writing special terminal control sequences (intentionally or not) to its output. This'll happen from time to time (catting a random binary file will very likely mess up your terminal as you'll likely encounter a byte sequence that's somehow special to the terminal). The solution is to run reset in the terminal (see man reset for more details)--you'll have to type it in blindly.

If you don't want rtorrent to do that, redirecting its stdout and stderr (these are normally bound to your terminal) will most likely stop it from writing to your terminal. Apart from that, you could do system reset in the stop method to fix what rtorrent has done.

Below is a combination of the above:

#!/usr/bin/env ruby

def start
  @pid ||= Process.spawn "rtorrent" #, err: '/dev/null', out: '/dev/null'
  sleep 0.5
end
def stop
  Process.kill(9, @pid) if @pid
  @pid = nil
  system 'reset'
end

start


sleep 0.5
#some code there
stop
Sign up to request clarification or add additional context in comments.

2 Comments

OK, then using popen was not good idea. I'm reaaly don't interested in reading or writing to that process. I tried to use fork{exec('rtorrent')} instead of popen, but result was same
I updated my answer to correspond to your UPDATE. Note: Process.spawn is essential fork{ exec('...') } as far as I know.

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.