Lauch a background process in Ruby and regist the PID - ruby

What is the best way to launch multiple process in background with ruby ? I need to use Thread.new ?
I have like 5 process to launch in background then i want to get the pid to stop properly all the process.In bash i can do it easyli:
htop &
echo $! >/tmp/htop.pid
And to kill:
kill `cat /tmp/htop.pid`
I want to be able to do the same thing with Ruby

You could use spawn:
pid = spawn('htop')
And to Process.kill:
Process.kill('TERM', pid)

Related

Bash: Start and kill child process

I have a program I want to start. Let' say this program will run a while(true)-loop (so it does not terminate. I want to write a bash script which:
Starts the program (./endlessloop &)
Waits 1 second (sleep 1)
Kills the program --> How?
I cannot use $! to get pid from child because server is running a lot of instances concurrently.
Store the PID:
./endlessloop & endlessloop_pid=$!
sleep 1
kill "$endlessloop_pid"
You can also check whether the process is still running with kill -0:
if kill -0 "$endlessloop_pid"; then
echo "Endlessloop is still running"
fi
...and storing the content in a variable means it scales to multiple processes:
endlessloop_pids=( ) # initialize an empty array to store PIDs
./endlessloop & endlessloop_pids+=( "$!" ) # start one in background and store its PID
./endlessloop & endlessloop_pids+=( "$!" ) # start another and store its PID also
kill "${endlessloop_pids[#]}" # kill both endlessloop instances started above
See also BashFAQ #68, "How do I run a command, and have it abort (timeout) after N seconds?"
The ProcessManagement page on the Wooledge wiki also discusses relevant best practices.
You can use the pgrep command for the same:
kill $(pgrep endlessloop)

Unable to kill nohup process

If I start the script by ./test.sh &, I am able to kill using kill -SIGINT PID.
But if I start my shell script using nohup ./test.sh & I am unable to kill the process using kill -SIGINT PID.
Kindly need your advice to kill the script using kill -SIGINT PID
The SIGINT signal means interrupt from keyboard; that's why it terminates a script run in foreground, but not in background neither using nohup.
To properly terminate your process use kill -TERM PID, which works in the 3 cases.

Capistrano Task to kill a process by port ONLY IF the process is running?

I pretty much need what my Question statement says, currently I have a Capistrano task that looks like this:
desc "stops private pub"
task :stop_private_pub do
run "kill -9 $(lsof -i:9292 -t)"
end
before 'deploy', 'servers:stop_private_pub'
...And it works well when in fact the process in port 9292 is running, The problem is that when the process Isn't running this task will FAIL! and it Halts the whole Deployment Process!
I'm not a UNIX Shell expert, nor am I a Capistrano master, so.. I really need help improving this Capistrano Task, Is there a way to kill -9 only if the process is running?
How can I do this?
Thanks in advance.
You could use Capistrano's capture command (in V3 at least, probably a V2 equivalent) to grab the output from your lsof command, and then only if you get a PID run the kill command.
pid = capture 'lsof', '-i:9292', '-t'
if pid # ensure it's valid here
run "kill -9 #{pid}" # make darn sure pid is an integer if you embed it
end
You could also do:
run "kill -9 $(lsof -i:9292 -t); true"
or add on error continue:
task :stop_web, :roles => :app, :on_error => :continue do
run "dosomething.sh; true"
end

How to quickly kill java processes in bash?

On a linux box, I have at most 3 java jars files running. How do I quickly kill all 3 with one command?
Usually I would:
ps ex - get the processes running
then find the process ids then do:
kill -9 #### #### ####
Any way to shorten this process? My eyes hurts from squinting to find the process ids.
My script does the following:
nohup ./start-gossip &
nohup ./start &
nohup ./start-admin &
Is there a way to get the process ids of each without looking it up?
Short answer:
pkill java
This looks up a process (or processes) to kill by name. This will find any other java processes too, so be careful. It also accepts -9, but you should avoid using -9 unless something is really broken.
EDIT:
Based on updates, you may be able to specify the script names to pkill as well (I'm not positive). But, the more traditional way to handle this issue is to leave pid files around. After you start a new process and background it, its pid is available in $!. If you write that pid to a file, then it's easy to check if the process is still running and kill just the processes you mean to. There is some chance that the pid will be reused, however.
You can save the PIDs when you start the processes so you can use them later:
nohup ./start-gossip &
START_GOSSIP_PID=$!
nohup ./start &
START_PID=$!
nohup ./start-admin &
START_ADMIN_PID=$!
...
kill -9 $START_GOSSIP_PID
kill -9 $START_PID
kill -9 $START_ADMIN_PID
This has the advantage (over pkill) of not killing off any other processes that coincidentally have similar names. If you don't want to perform the kill operation from the script itself, but just want to have the PIDs handy, write them to a file (from the script):
echo $START_GOSSIP_PID > /some/path/start_gossip.pid
Or even just do this when you launch the process, rather than saving the PID to a variable:
nohup ./start-gossip &
echo $! > /some/path/start_gossip.pid
To get the process id of that java process run
netstat -tuplen
Process ID (PID) of that process whom you want to kill and run
kill -9 PID

how to stop sinatra from running?

If ruby myapp.rb starts sinatra previewing at localhost:4567, how can I programatically stop/halt/kill it? Terminal command (other than Ctrl-C), or Rake tasks would be fine.
I need to incorporate this into a Rake task or terminal.
In myapp.rb, add this before sinatra starts:
puts "This is process #{Process.pid}"
When you want to kill it, do this in a shell:
kill <pid>
Where <pid> is the number outputted by myapp.rb. If you want to do it in ruby:
Process.kill 'TERM', <pid>
Both of these will let sinatra run it's exit routine. If you don't want to type in the pid every time, have myapp.rb open a file and put it's pid in it. Then when you want to stop it, read the file and use that. Example:
# myapp.rb:
File.open('myapp.pid', 'w') {|f| f.write Process.pid }
# shell:
kill `cat myapp.pid`
# ruby:
Process.kill 'TERM', File.read('myapp.pid')
In OS X, from the command line (Terminal.app, or DTerm) just enter:
$ killall ruby
every ruby process will stop. Sinatra too.
In Linux (and other UNIXes), you can:
$ ps aux | grep ruby
$ kill <ruby-process-id>
The simples way to do that:
kill #{Process.pid}
To do this in a simple repeatable way, there's a few methods.
Record the PID as you start your Sinatra server, e.g.
# Run the Sinatra server and send it to background (using &)
ruby my_sinatra_server.rb &
# Record the PID of the last background process (using $!)
MY_SINATRA_SERVER_PID=$!
# Now go ahead and do your stuff...
# When finished, kill the sinatra server (from the same shell)
kill $MY_SINATRA_SERVER_PID
Instead of using an env variable ($MY_SINATRA_SERVER) you can use a temporary file e.g. my_sinatra_server.pid
# Run the Sinatra server and send it to background (using &)
ruby my_sinatra_server.rb &
# Record the PID of the last background process (using $!)
echo $! > my_sinatra_server.pid
# Now go ahead and do your stuff...
# When finished, kill the sinatra server (from the same shell)
kill $(< my_sinatra_server.pid)

Resources