DEV Community

Connor Bode
Connor Bode

Posted on

Running (and killing) multiple processes in a single shell script

Something I'm regularly doing during my daily development is running build / server processes.

For example, right now I'm working on a project that requires a Django development web server as well as a sass --watch process to compile CSS. Often I'm also running some node processes like react-native or babel or something.

For me, it's annoying to have 10 terminals open running all of these processes.

I'd rather run it in a single file. A common solution is to use the latest build utility to wire everything up. My opinion is that it's more useful & natural to just call the binaries directly from a bash script.

Here's how you can run multiple processes at once (assuming we have binaries or shell scripts called program_1, program_2, and program_3):

# start the first program and fork it
program_1 &

# store the process ID
program_1_pid=$!

# start the second program and fork it
program_2 &

# store the process ID
program_2_pid=$!

# trap ctrl-c so that we can kill
# the first two programs
trap onexit INT
function onexit() {
  kill -9 $program_1_pid
  kill -9 $program_2_pid
}

# start the third program, don't fork it
program_3

That's it. Name this script something like script.sh and run it using bash script.sh. All three of your programs will run. When you exit (by pressing ctrl+c), first program_3 will quit, then the function onexit will execute, stopping the other two programs.


That's all for now, hopefully this will help you in your dev life.

Follow me here on dev.to or on Twitter @connorbode for more as I learn & build.

Top comments (6)

Collapse
 
coolvikas profile image
Vikas Kumar

I could not understand the meaning of 'INT' in the trap part of script

Collapse
 
connorbode profile image
Connor Bode

I'll explain what I know but I dont have a very deep understanding here (maybe someone else can jump in with more info).

When you hit ctrl-c you send a SIGINT to the script running in your terminal. It's called a "signal" and SIGINT is one of many signals that exist on unix systems.

Think of it like an event that occurs. A "trap" is just an event handler for a signal.

Here's some additional reading on signals: en.m.wikipedia.org/wiki/Signal_(IPC)

Collapse
 
coolvikas profile image
Vikas Kumar

Thanks, Connor for the explanation but I want to know the specific detail on 'INT'
Is INT and SIGINT the same?

Thread Thread
 
connorbode profile image
Connor Bode

Yes, the INT you see in the script is SIGINT, which is an "interrupt signal"

Thread Thread
 
coolvikas profile image
Vikas Kumar

Thanks, Connor it was helpful

Collapse
 
willtemperley profile image
willtemperley

Thanks! I've found this a much simpler way to run Vite and a bunch of microservices than with Lerna and Turborepo. There seems to be more control over order of execution this way, i.e. start the services before the web app. I also found both build systems prone to leaving zombie processes, it gets boring quickly hunting those down.