Created
December 31, 2025 04:05
-
-
Save Khuirul-Huda/e0d86ab203bcfe2f3c27c04e95db271c to your computer and use it in GitHub Desktop.
convert-systemd-unit-to-runit.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Configuration | |
| SYSD_DIR="/usr/lib/systemd/system" | |
| RUNIT_DIR="/etc/sv" | |
| SERVICE_DIR="/etc/service" | |
| # Ensure we are root | |
| if [ "$EUID" -ne 0 ]; then | |
| echo "Please run as root" | |
| exit 1 | |
| fi | |
| mkdir -p "$RUNIT_DIR" | |
| for service_file in "$SYSD_DIR"/*.service; do | |
| [ -e "$service_file" ] || continue | |
| # Skip symlinks and templates | |
| if [ -L "$service_file" ] || [[ "$service_file" == *"@"* ]]; then | |
| continue | |
| fi | |
| NAME=$(basename "$service_file" .service) | |
| SV_PATH="$RUNIT_DIR/$NAME" | |
| # EXCEPTION: Skip if already exists | |
| if [ -d "$SV_PATH" ]; then | |
| echo "Skipping '$NAME': Runit directory already exists." | |
| continue | |
| fi | |
| # Extract core data | |
| EXEC_START=$(grep '^ExecStart=' "$service_file" | head -n 1 | sed 's/^ExecStart=//') | |
| USER=$(grep '^User=' "$service_file" | head -n 1 | sed 's/^User=//') | |
| if [ -z "$EXEC_START" ]; then | |
| continue | |
| fi | |
| # CLEANUP: Remove common daemonization flags | |
| EXEC_START=$(echo "$EXEC_START" | sed -E 's/(\s|^)(-[dD]|--daemonize|--daemon)(\s|$)/ /g') | |
| echo "Converting $NAME..." | |
| mkdir -p "$SV_PATH/log" | |
| # --- Generate 'run' script using printf --- | |
| printf "#!/bin/sh\nexec 2>&1\necho \"Starting %s...\"\n\n" "$NAME" > "$SV_PATH/run" | |
| # Handle EnvironmentFile= | |
| grep '^EnvironmentFile=' "$service_file" | sed 's/^EnvironmentFile=-//;s/^EnvironmentFile=//' | while read -r env_file; do | |
| if [ -f "$env_file" ]; then | |
| printf "set -a; . %s; set +a\n" "$env_file" >> "$SV_PATH/run" | |
| fi | |
| done | |
| # Handle inline Environment= | |
| grep '^Environment=' "$service_file" | sed 's/^Environment=//' | while read -r env_line; do | |
| printf "export %s\n" "$env_line" >> "$SV_PATH/run" | |
| done | |
| # Final execution line | |
| if [ -n "$USER" ]; then | |
| printf "\nexec chpst -u %s %s\n" "$USER" "$EXEC_START" >> "$SV_PATH/run" | |
| else | |
| printf "\nexec %s\n" "$EXEC_START" >> "$SV_PATH/run" | |
| fi | |
| # --- Generate 'log/run' script using printf (Safe alternative to EOF) --- | |
| printf "#!/bin/sh\nmkdir -p /var/log/%s\nexec svlogd -tt /var/log/%s\n" "$NAME" "$NAME" > "$SV_PATH/log/run" | |
| # Set permissions | |
| chmod +x "$SV_PATH/run" "$SV_PATH/log/run" | |
| # Create the symlink | |
| if [ ! -L "$SERVICE_DIR/$NAME" ]; then | |
| ln -s "$SV_PATH" "$SERVICE_DIR/$NAME" | |
| echo "Successfully activated $NAME" | |
| fi | |
| done | |
| echo "Batch conversion finished." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment