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:

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;)
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With