0

I have a script that looks like this. Invoked with ./myscript.sh start

#!/bin/bash
if [[ "$1" == "start" ]]; then
  echo "Dev start script process ID: $$"

  cd /my/path1
  yarn dev &> /my/path/logs/log1.log &
  echo "started process1 in background"
  echo "Process ID: $!"
  echo "Logging output at logs/log1.log"
  sleep 2

  cd /my/path2
  yarn start:dev &> /my/path/logs/log2.log &
  echo "started process2 in background"
  echo "Process ID: $!"
  echo "Logging output at logs/log2.log"
  sleep 2

  cd /my/path2
  yarn dev &> /my/path/logs/log3.log &
  echo "started process3 in background"
  echo "Process ID: $!"
  echo "Logging output at logs/log3.log"
elif [[ "$1" == "stop" ]]; then
  killList=`ps  | grep node | awk '{print $1}'`
  if [[ $killList != "" ]]; then
      echo $killList | xargs kill
      echo  "Processes killed: $killList"
  else
      echo "Nothing to stop"
  fi
else
  echo "Invalid argument"
fi

When i run ps after I run this script, i can see a bunch of node processes (more than 3) that I assume has been started by the yarn dev commands. I want to run ./myscript.sh stop and stop all the node processes that were spawned from my previous run of ./myscript.sh start

How do I make this happen?

6
  • Can you show us what you've tried already ? Please edit OP to include the new info.
    – Cbhihe
    Jun 19 at 20:50
  • The closest I was able to get to what I want is already in the OP. It can successfully kill the current node processes spawned by my script. I started with killall node and was able to work it out till here (the elif block)
    – Jay Pillai
    Jun 19 at 21:16
  • You want a completely separate instance of the script to kill processes launched by the first instance? Or do you want to have the same script, which is still running, kill its child processes?
    – terdon
    Jun 19 at 23:16
  • @terdon I want a completely separate instance of the script to kill everything launched by my first instance. My script as it currentlly is, does the latter one you described, kills all the child node processes.
    – Jay Pillai
    Jun 19 at 23:47
  • So how would the script know what processes to kill? What if something else launched a node process? Do you just want to kill all running node processes irrespective of who started them? Are you just looking for killall node or pkill node?
    – terdon
    Jun 19 at 23:53

1 Answer 1

1

You could get the list of processes directly spawned from that bash and send SIGTERM to them:

pgrep -P $$ --signal SIGTERM

$$ is the process number of the current bash script.

Depending on how the signal is treated by the child processes, that might or not kill the grandchild processes (and so on, recursively).

So another way to do it is to get list the whole tree of processes starting at your bash and then kill them.

pstree -A -p $$ | grep -Eow "[0-9]+" | xargs kill

pstree outputs the tree (formatted for humans), grep extracts the process numbers and then you do what you need to do with them, for example running kill for each one.

Note that with the line above pstree will also list the grep and xargs processes, so you will have two No such process warnings from kill. Not sure if there is a race condition, that's just a proof of concept. You can code the right side of the pipeline to deal with the list of processes properly, filter, etc.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.