All checks were successful
Reindex Knowledge Base / reindex (push) Successful in 3s
Adds title, description, type, domain, and tags frontmatter to every doc for improved KB semantic search. The description field is prepended to every search chunk, and domain/type/tags enable filtered queries. Type values: context, guide, runbook, reference, troubleshooting Domain values match directory structure (networking, docker, etc.) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
153 lines
3.3 KiB
Markdown
153 lines
3.3 KiB
Markdown
---
|
|
title: "Bash Service Management Examples"
|
|
description: "Bash script examples for systemd service installation, lifecycle management (start/stop/restart/status/logs), and process monitoring with PID-based health checks and auto-restart."
|
|
type: reference
|
|
domain: development
|
|
tags: [bash, systemd, service-management, process-monitoring, scripting]
|
|
---
|
|
|
|
# Bash Service Management Examples
|
|
|
|
## Systemd Service Script
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
SERVICE_NAME="myapp"
|
|
SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service"
|
|
|
|
usage() {
|
|
echo "Usage: $0 {install|start|stop|restart|status|logs|uninstall}"
|
|
exit 1
|
|
}
|
|
|
|
install_service() {
|
|
echo "Installing ${SERVICE_NAME} service..."
|
|
|
|
sudo tee "$SERVICE_FILE" > /dev/null << EOF
|
|
[Unit]
|
|
Description=My Application Service
|
|
After=network.target
|
|
Wants=network.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=myapp
|
|
Group=myapp
|
|
WorkingDirectory=/opt/myapp
|
|
ExecStart=/opt/myapp/bin/myapp
|
|
Restart=always
|
|
RestartSec=10
|
|
Environment=NODE_ENV=production
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable "$SERVICE_NAME"
|
|
echo "Service installed and enabled"
|
|
}
|
|
|
|
manage_service() {
|
|
local action="$1"
|
|
echo "${action^}ing ${SERVICE_NAME} service..."
|
|
sudo systemctl "$action" "$SERVICE_NAME"
|
|
echo "Service ${action}ed successfully"
|
|
}
|
|
|
|
show_status() {
|
|
echo "=== Service Status ==="
|
|
sudo systemctl status "$SERVICE_NAME" --no-pager -l
|
|
echo
|
|
echo "=== Service Logs (last 20 lines) ==="
|
|
sudo journalctl -u "$SERVICE_NAME" --no-pager -n 20
|
|
}
|
|
|
|
show_logs() {
|
|
echo "Following logs for ${SERVICE_NAME}..."
|
|
sudo journalctl -u "$SERVICE_NAME" -f
|
|
}
|
|
|
|
uninstall_service() {
|
|
echo "Uninstalling ${SERVICE_NAME} service..."
|
|
sudo systemctl stop "$SERVICE_NAME" || true
|
|
sudo systemctl disable "$SERVICE_NAME" || true
|
|
sudo rm -f "$SERVICE_FILE"
|
|
sudo systemctl daemon-reload
|
|
echo "Service uninstalled"
|
|
}
|
|
|
|
case "${1:-}" in
|
|
install)
|
|
install_service
|
|
;;
|
|
start|stop|restart)
|
|
manage_service "$1"
|
|
;;
|
|
status)
|
|
show_status
|
|
;;
|
|
logs)
|
|
show_logs
|
|
;;
|
|
uninstall)
|
|
uninstall_service
|
|
;;
|
|
*)
|
|
usage
|
|
;;
|
|
esac
|
|
```
|
|
|
|
## Process Monitoring Script
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
PROCESS_NAME="myapp"
|
|
RESTART_COMMAND="/opt/myapp/start.sh"
|
|
LOG_FILE="/var/log/myapp-monitor.log"
|
|
PID_FILE="/var/run/myapp.pid"
|
|
|
|
log_message() {
|
|
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
|
|
}
|
|
|
|
check_process() {
|
|
if [[ -f "$PID_FILE" ]]; then
|
|
local pid=$(cat "$PID_FILE")
|
|
if kill -0 "$pid" 2>/dev/null; then
|
|
return 0 # Process is running
|
|
else
|
|
rm -f "$PID_FILE"
|
|
return 1 # Process is not running
|
|
fi
|
|
else
|
|
return 1 # PID file doesn't exist
|
|
fi
|
|
}
|
|
|
|
restart_process() {
|
|
log_message "Attempting to restart $PROCESS_NAME..."
|
|
if $RESTART_COMMAND; then
|
|
log_message "$PROCESS_NAME restarted successfully"
|
|
else
|
|
log_message "Failed to restart $PROCESS_NAME"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
main() {
|
|
if ! check_process; then
|
|
log_message "$PROCESS_NAME is not running"
|
|
restart_process
|
|
else
|
|
log_message "$PROCESS_NAME is running normally"
|
|
fi
|
|
}
|
|
|
|
main "$@"
|
|
``` |