I sometimes have to use kill -9 as a last resort to kill my rails server. Unfortunately, I have to do that often enough that I wrote a helper function in my bash_profile to do it.If I do it manually -- ps aux | grep '[r]ails], grab the pid (eg. 12345), and kill -9 12345 -- it kills the server and leaves the browser intact. But my function kills the browser too, which I don't want to do:function running {  ps -p $(lsof -i :3000 -t) &> /dev/null}function k9 {  if running  then    kill -9 $(lsof -i :3000 -t)  else    echo Rails server is not running  fi}I've confirmed that lsof -i :3000 -t grabs the same pid as I'm getting from ps aux, so what am I doing wrong?
Why is 'kill -9' killing browser as well as server?
bash;shell script;kill
The problem:With lsof -i :3000 -t, you will look for any processes connected to a port 3000, which may be on the remote side.In the cases where you use your script, the browser seems to have a connetction to the rails server on port 3000. The difference is in the timing between using the browser and using kill.  That means the browser is listed  in the output of lsof too, and killed.You should better kill processes that look like your rails server, not anything that is using a port 3000, locally or elsewhere.The general solution:pkill is the right tool for the job.For trying what is matched, use pgrep, which matches the same way:If the command line of the server, as shown in ps, starts with a command name that identifies your server instance, you can use pkill servercommand.If you need to match a part of the command line arguments, add -f, like pkill -f serverargument.The processes that are killed by pkill will just be listed by pgrep - so use that to try what will be killed. Add the option -a to pgrep to list the command line, instead of the pid only.Examples for pgrep / pkill:As an example for using -f: According to ps, these two instances of xbindkeys are running: $ ps aux|grep '[x]bindkeys'26719 ?        S      0:00 xbindkeys -f /tmp/xbindkeysrc-tmp32046 ?        S      0:00 xbindkeys -f /home/auser/.xbindkeysrcNow I can find both instances with:$ pgrep xbindkeys2671932046Or showing the commands:$ pgrep -a xbindkeys26719 xbindkeys -f /tmp/xbindkeysrc-tmp32046 xbindkeys -f /home/auser/.xbindkeysrcOr match one of the instances by the command line arguments:$ pgrep -f '/home/auser/.xbindkeysrc'32046Without -f, none of the processes are matched:$ pgrep '/home/auser/.xbindkeysrc'Finally, sending the process a signal, like with kill:$ pkill -f '/home/auser/.xbindkeysrc'Alternative solution based on original approach:The solution with pkill is much more general, but to follow your original approach, the lsof command can be made more strict to matchany local server listening on the port,instead ofany program using the local port in any way, or using a remote port of that number in any way.The option -sTCP:LISTEN restricts the list to ports listening on, and, as only local ports can be listened on, also to local ports only.It could be used as a if test like this:if lsof -i :3000 -sTCP:LISTEN -t >/dev/null ; then    echo runningelse    echo not runningfiSide note on using SIGKILL, as in kill -9:The KILL signal can be used with pkill just the same way as with kill:$ pkill -9 -f '/home/auser/.xbindkeysrc'But in most general cases, that has no advantage above the default signal -15, and in some cases, it breaks things. So it's not a good idea to make it a habit. Take a look at When should I not kill -9 a process? to understand why you do not want to use -9 by default. 