BASH
Manage Multiple Local Development Services
Bash script to start, stop, or manage multiple background services or commands for a local web development environment, streamlining workflow.
#!/bin/bash
# Define your services/commands
SERVICES=(
"frontend:cd frontend && npm start"
"backend:cd backend && npm run dev"
"database:docker-compose up -d db"
)
ACTION="$1"
function start_service() {
local name="$1"
local cmd="$2"
echo "Starting $name..."
eval "$cmd" &> /dev/null &
echo "$!" > "/tmp/${name// /_}.pid"
echo "$name started (PID: $(cat "/tmp/${name// /_}.pid"))"
}
function stop_service() {
local name="$1"
local pid_file="/tmp/${name// /_}.pid"
if [ -f "$pid_file" ]; then
local pid=$(cat "$pid_file")
echo "Stopping $name (PID: $pid)..."
kill "$pid"
rm "$pid_file"
echo "$name stopped."
else
echo "$name is not running or PID file not found."
fi
}
function status_service() {
local name="$1"
local pid_file="/tmp/${name// /_}.pid"
if [ -f "$pid_file" ]; then
local pid=$(cat "$pid_file")
if ps -p "$pid" &> /dev/null; then
echo "$name is RUNNING (PID: $pid)"
else
echo "$name is NOT RUNNING (stale PID file)."
rm "$pid_file"
fi
else
echo "$name is NOT RUNNING."
fi
}
case "$ACTION" in
start)
for service_entry in "${SERVICES[@]}"; do
IFS=':' read -r name cmd <<< "$service_entry"
start_service "$name" "$cmd"
done
echo "All services started. Check /tmp/*.pid for PIDs."
;;
stop)
for service_entry in "${SERVICES[@]}"; do
IFS=':' read -r name cmd <<< "$service_entry"
stop_service "$name"
done
echo "All services stopped."
;;
restart)
"$0" stop
sleep 2
"$0" start
;;
status)
for service_entry in "${SERVICES[@]}"; do
IFS=':' read -r name cmd <<< "$service_entry"
status_service "$name"
done
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
How it works: This script simplifies managing multiple services common in local web development environments (e.g., frontend, backend, database). It allows starting services in the background, stopping them gracefully via PID files, checking their status, or restarting them. This streamlines the setup and teardown process for developers, improving efficiency and reducing manual command repetition.