#!/bin/bash # Script to extract service files and selectively enable/start them # Make sure to run with sudo privileges # Set the source directory (current directory/services) SOURCE_DIR="services" TARGET_DIR="/etc/systemd/system" # Set timezone to Asia/Bangkok set_timezone() { echo "Setting timezone to Asia/Bangkok..." timedatectl set-timezone Asia/Bangkok if [ $? -eq 0 ]; then echo "Timezone successfully set to Asia/Bangkok" echo "Current time: $(date)" else echo "Warning: Could not set timezone. Continuing anyway..." fi echo "" } # Array to store our services services_array=() total_services=0 # Function to extract services extract_services() { # Check if source directory exists if [ ! -d "$SOURCE_DIR" ]; then echo "Error: Source directory '$SOURCE_DIR' not found!" echo "Make sure you're running this script from the correct location." exit 1 fi # Check if running as root or with sudo if [ "$EUID" -ne 0 ]; then echo "This script requires root privileges to copy to $TARGET_DIR" echo "Please run with: sudo ./script.sh" exit 1 fi # Copy all .service files from services folder to systemd directory echo "Copying service files from $SOURCE_DIR to $TARGET_DIR..." cp "$SOURCE_DIR"/*.service "$TARGET_DIR"/ # Check if copy was successful if [ $? -eq 0 ]; then echo "Successfully copied all service files to $TARGET_DIR" # Reload systemd to recognize new services echo "Reloading systemd daemon..." systemctl daemon-reload echo "Service files have been installed and systemd has been reloaded." else echo "Error: Failed to copy service files. Please check permissions." exit 1 fi } # Function to load services from source directory load_services() { services_array=() total_services=0 local i=1 for service in "$SOURCE_DIR"/*.service; do if [ -f "$service" ]; then service_name=$(basename "$service") services_array[$i]="$service_name" ((i++)) fi done total_services=$((i-1)) } # Function to display available services (only from our source directory) show_services() { echo "" echo "Available services (from $SOURCE_DIR):" echo "======================================" if [ $total_services -eq 0 ]; then echo "No services found in $SOURCE_DIR directory!" return fi for ((i=1; i<=$total_services; i++)); do echo "$i. ${services_array[$i]}" done } # Function to show current running services show_running_services() { echo "" echo "Currently running services:" echo "===========================" local found_running=0 for ((i=1; i<=$total_services; i++)); do service_name="${services_array[$i]}" status=$(systemctl is-active "$service_name" 2>/dev/null) # Check if service is active (running) if [[ "$status" == "active" ]]; then enabled=$(systemctl is-enabled "$service_name" 2>/dev/null || echo "disabled") echo "$i. $service_name - Active: $status, Enabled: $enabled" found_running=1 fi done if [ $found_running -eq 0 ]; then echo "No running services found." fi echo "" } # Function to show only activated services show_activated_services() { echo "" echo "Activated services:" echo "===================" local found_activated=0 for ((i=1; i<=$total_services; i++)); do service_name="${services_array[$i]}" status=$(systemctl is-active "$service_name" 2>/dev/null) # Check if service is active (running) if [[ "$status" == "active" ]]; then enabled=$(systemctl is-enabled "$service_name" 2>/dev/null || echo "disabled") echo "$i. $service_name - Active: $status, Enabled: $enabled" found_activated=1 fi done if [ $found_activated -eq 0 ]; then echo "No activated services found." echo "Use options 1 or 3 to start services." fi } # Function to view service file view_service() { local service_num=$1 if [[ $service_num -ge 1 && $service_num -le $total_services ]]; then service_name="${services_array[$service_num]}" service_file="$TARGET_DIR/$service_name" if [ -f "$service_file" ]; then echo "" echo "Viewing service file: $service_name" echo "==========================================" cat "$service_file" else echo "Service file not found: $service_file" fi else echo "Invalid service number!" fi } # Function to edit service file with nano edit_service() { local service_num=$1 if [[ $service_num -ge 1 && $service_num -le $total_services ]]; then service_name="${services_array[$service_num]}" service_file="$TARGET_DIR/$service_name" if [ -f "$service_file" ]; then echo "" echo "Editing service file: $service_name" echo "Note: After editing, run 'systemctl daemon-reload' and restart the service for changes to take effect." echo "==========================================" # Edit the service file with nano nano "$service_file" # Ask if user wants to reload daemon and restart the service echo "" read -p "Do you want to reload systemd daemon and restart the service? (y/N): " reload_choice if [[ $reload_choice == "y" || $reload_choice == "Y" ]]; then echo "Reloading systemd daemon..." systemctl daemon-reload # Check if service is active if systemctl is-active "$service_name" --quiet; then echo "Restarting $service_name..." systemctl restart "$service_name" echo "Service restarted successfully." else echo "Service is not currently running. Changes will take effect when started." fi else echo "Remember to run 'systemctl daemon-reload' and restart the service later for changes to take effect." fi else echo "Service file not found: $service_file" fi else echo "Invalid service number!" fi } # Function to validate time range input validate_time_range() { local range=$1 if [[ ! "$range" =~ ^[0-9]{1,2}-[0-9]{1,2}$ ]]; then return 1 fi IFS='-' read -ra times <<< "$range" local start=${times[0]} local end=${times[1]} if [[ $start -lt 0 || $start -gt 23 || $end -lt 0 || $end -gt 23 ]]; then return 1 fi if [[ $start -ge $end ]]; then return 1 fi return 0 } # Function to create systemd timer for starting and stopping a service in range schedule_service_range() { local service_num=$1 if [[ $service_num -ge 1 && $service_num -le $total_services ]]; then service_name="${services_array[$service_num]}" echo "" echo "Scheduling automatic START and STOP for: $service_name" echo "==========================================" echo "Enter time range in 24-hour format (start-end):" echo "Examples:" echo " - 6-8 (Start at 6 AM, Stop at 8 AM)" echo " - 9-17 (Start at 9 AM, Stop at 5 PM)" echo " - 22-4 (Start at 10 PM, Stop at 4 AM - next day)" echo "" echo "Current timezone: $(timedatectl show --property=Timezone --value)" echo "Current time: $(date)" echo "" read -p "Enter time range (start-end, 0-23): " time_range if [[ -z "$time_range" ]]; then echo "No time range entered. Scheduling cancelled." return fi # Validate time range if ! validate_time_range "$time_range"; then echo "Invalid time range format!" echo "Please use format: start-end (0-23) where start < end" echo "Examples: 6-8, 9-17, 22-4" return fi IFS='-' read -ra times <<< "$time_range" local start_hour=${times[0]} local end_hour=${times[1]} # Format hours with leading zeros printf -v start_hour_formatted "%02d" $start_hour printf -v end_hour_formatted "%02d" $end_hour echo "" echo "Scheduling configuration:" echo " - Service: $service_name" echo " - Start time: ${start_hour_formatted}:00:00 (${start_hour}:00 AM/PM)" echo " - Stop time: ${end_hour_formatted}:00:00 (${end_hour}:00 AM/PM)" echo " - Timezone: Asia/Bangkok" echo "" # Create start timer start_timer_name="${service_name%.service}-start.timer" start_timer_file="$TARGET_DIR/$start_timer_name" cat > "$start_timer_file" << EOF [Unit] Description=Timer to start ${service_name} daily at ${start_hour_formatted}:00 Requires=${service_name} [Timer] OnCalendar=*-*-* ${start_hour_formatted}:00:00 Persistent=true [Install] WantedBy=timers.target EOF # Create start service start_service_file="$TARGET_DIR/${service_name%.service}-start.service" cat > "$start_service_file" << EOF [Unit] Description=Start ${service_name} After=network.target [Service] Type=oneshot ExecStart=/bin/systemctl start ${service_name} User=root [Install] WantedBy=multi-user.target EOF # Create stop timer stop_timer_name="${service_name%.service}-stop.timer" stop_timer_file="$TARGET_DIR/$stop_timer_name" cat > "$stop_timer_file" << EOF [Unit] Description=Timer to stop ${service_name} daily at ${end_hour_formatted}:00 Requires=${service_name} [Timer] OnCalendar=*-*-* ${end_hour_formatted}:00:00 Persistent=true [Install] WantedBy=timers.target EOF # Create stop service stop_service_file="$TARGET_DIR/${service_name%.service}-stop.service" cat > "$stop_service_file" << EOF [Unit] Description=Stop ${service_name} After=network.target [Service] Type=oneshot ExecStart=/bin/systemctl stop ${service_name} User=root [Install] WantedBy=multi-user.target EOF # Enable and start both timers systemctl daemon-reload systemctl enable "$start_timer_name" systemctl start "$start_timer_name" systemctl enable "$stop_timer_name" systemctl start "$stop_timer_name" echo "Scheduling completed successfully!" echo "" echo "Created timers:" echo " - $start_timer_name (starts at ${start_hour_formatted}:00)" echo " - $stop_timer_name (stops at ${end_hour_formatted}:00)" echo "" echo "Check timer status with:" echo " systemctl status $start_timer_name" echo " systemctl status $stop_timer_name" echo "" echo "View all timers with: systemctl list-timers" else echo "Invalid service number!" fi } # Function to show scheduled timers show_scheduled_timers() { echo "" echo "Scheduled Timers (Asia/Bangkok time):" echo "=====================================" local found_timers=0 for ((i=1; i<=$total_services; i++)); do service_name="${services_array[$i]}" base_name="${service_name%.service}" # Check for start timers start_timer="${base_name}-start.timer" if systemctl list-timers | grep -q "$start_timer"; then echo "$i. START: $service_name" systemctl list-timers | grep "$start_timer" echo "" found_timers=1 fi # Check for stop timers stop_timer="${base_name}-stop.timer" if systemctl list-timers | grep -q "$stop_timer"; then echo "$i. STOP: $service_name" systemctl list-timers | grep "$stop_timer" echo "" found_timers=1 fi done if [ $found_timers -eq 0 ]; then echo "No scheduled timers found." echo "Use option 10 to schedule service start/stop times." fi } # Function to show menu show_menu() { echo "" echo "==========================================" echo " Service Management Menu" echo "==========================================" show_services echo "" echo "Basic Operations:" echo "1. Enable and start service(s)" echo "2. Enable service(s) (start at boot)" echo "3. Start service(s) (run now)" echo "4. Stop service(s)" echo "5. Disable service(s)" echo "6. Check service status" echo "7. Show activated services status" echo "8. Edit service file (nano)" echo "" echo "Scheduling Operations:" echo "9. Show scheduled timers" echo "10. Schedule service automatic START/STOP range" echo "" echo "11. Exit" echo "" } # Function to manage multiple services manage_multiple_services() { # Load services from source directory load_services if [ $total_services -eq 0 ]; then echo "No services found to manage!" return fi while true; do show_menu read -p "Choose an option (1-11): " option case $option in 1) show_running_services echo "" echo "Enter service numbers to ENABLE AND START (e.g., 1 3 5 or 1-5 or 'all'): " read -p "Services to manage: " service_input # Process the service selection selected_services=() if [[ "$service_input" == "all" ]]; then # Select all services for ((i=1; i<=$total_services; i++)); do selected_services+=("${services_array[$i]}") done elif [[ "$service_input" =~ ^[0-9]+-[0-9]+$ ]]; then # Handle ranges (e.g., 1-5) IFS='-' read -ra range <<< "$service_input" start=${range[0]} end=${range[1]} for ((i=start; i<=end; i++)); do if [[ $i -ge 1 && $i -le $total_services ]]; then selected_services+=("${services_array[$i]}") fi done else # Handle individual numbers (e.g., 1 3 5) for num in $service_input; do if [[ $num -ge 1 && $num -le $total_services ]]; then selected_services+=("${services_array[$num]}") fi done fi # Execute the action on selected services if [ ${#selected_services[@]} -eq 0 ]; then echo "No valid services selected!" sleep 2 continue fi echo "" echo "Selected services: ${selected_services[@]}" echo "" for service_name in "${selected_services[@]}"; do echo "Enabling and starting $service_name..." systemctl enable "$service_name" systemctl start "$service_name" # Show status after action echo -n "Status: " systemctl is-active "$service_name" 2>/dev/null || echo "not-active" echo "" done ;; 2) show_running_services echo "" echo "Enter service numbers to ENABLE (start at boot) (e.g., 1 3 5 or 1-5 or 'all'): " read -p "Services to manage: " service_input # Process the service selection selected_services=() if [[ "$service_input" == "all" ]]; then # Select all services for ((i=1; i<=$total_services; i++)); do selected_services+=("${services_array[$i]}") done elif [[ "$service_input" =~ ^[0-9]+-[0-9]+$ ]]; then # Handle ranges (e.g., 1-5) IFS='-' read -ra range <<< "$service_input" start=${range[0]} end=${range[1]} for ((i=start; i<=end; i++)); do if [[ $i -ge 1 && $i -le $total_services ]]; then selected_services+=("${services_array[$i]}") fi done else # Handle individual numbers (e.g., 1 3 5) for num in $service_input; do if [[ $num -ge 1 && $num -le $total_services ]]; then selected_services+=("${services_array[$num]}") fi done fi # Execute the action on selected services if [ ${#selected_services[@]} -eq 0 ]; then echo "No valid services selected!" sleep 2 continue fi echo "" echo "Selected services: ${selected_services[@]}" echo "" for service_name in "${selected_services[@]}"; do echo "Enabling $service_name..." systemctl enable "$service_name" # Show status after action echo -n "Status: " systemctl is-active "$service_name" 2>/dev/null || echo "not-active" echo "" done ;; 3) show_running_services echo "" echo "Enter service numbers to START (run now) (e.g., 1 3 5 or 1-5 or 'all'): " read -p "Services to manage: " service_input # Process the service selection selected_services=() if [[ "$service_input" == "all" ]]; then # Select all services for ((i=1; i<=$total_services; i++)); do selected_services+=("${services_array[$i]}") done elif [[ "$service_input" =~ ^[0-9]+-[0-9]+$ ]]; then # Handle ranges (e.g., 1-5) IFS='-' read -ra range <<< "$service_input" start=${range[0]} end=${range[1]} for ((i=start; i<=end; i++)); do if [[ $i -ge 1 && $i -le $total_services ]]; then selected_services+=("${services_array[$i]}") fi done else # Handle individual numbers (e.g., 1 3 5) for num in $service_input; do if [[ $num -ge 1 && $num -le $total_services ]]; then selected_services+=("${services_array[$num]}") fi done fi # Execute the action on selected services if [ ${#selected_services[@]} -eq 0 ]; then echo "No valid services selected!" sleep 2 continue fi echo "" echo "Selected services: ${selected_services[@]}" echo "" for service_name in "${selected_services[@]}"; do echo "Starting $service_name..." systemctl start "$service_name" # Show status after action echo -n "Status: " systemctl is-active "$service_name" 2>/dev/null || echo "not-active" echo "" done ;; 4) show_running_services echo "" echo "Enter service numbers to STOP (e.g., 1 3 5 or 1-5 or 'all'): " read -p "Services to manage: " service_input # Process the service selection selected_services=() if [[ "$service_input" == "all" ]]; then # Select all services for ((i=1; i<=$total_services; i++)); do selected_services+=("${services_array[$i]}") done elif [[ "$service_input" =~ ^[0-9]+-[0-9]+$ ]]; then # Handle ranges (e.g., 1-5) IFS='-' read -ra range <<< "$service_input" start=${range[0]} end=${range[1]} for ((i=start; i<=end; i++)); do if [[ $i -ge 1 && $i -le $total_services ]]; then selected_services+=("${services_array[$i]}") fi done else # Handle individual numbers (e.g., 1 3 5) for num in $service_input; do if [[ $num -ge 1 && $num -le $total_services ]]; then selected_services+=("${services_array[$num]}") fi done fi # Execute the action on selected services if [ ${#selected_services[@]} -eq 0 ]; then echo "No valid services selected!" sleep 2 continue fi echo "" echo "Selected services: ${selected_services[@]}" echo "" for service_name in "${selected_services[@]}"; do echo "Stopping $service_name..." systemctl stop "$service_name" # Show status after action echo -n "Status: " systemctl is-active "$service_name" 2>/dev/null || echo "not-active" echo "" done ;; 5) show_running_services echo "" echo "Enter service numbers to DISABLE (e.g., 1 3 5 or 1-5 or 'all'): " read -p "Services to manage: " service_input # Process the service selection selected_services=() if [[ "$service_input" == "all" ]]; then # Select all services for ((i=1; i<=$total_services; i++)); do selected_services+=("${services_array[$i]}") done elif [[ "$service_input" =~ ^[0-9]+-[0-9]+$ ]]; then # Handle ranges (e.g., 1-5) IFS='-' read -ra range <<< "$service_input" start=${range[0]} end=${range[1]} for ((i=start; i<=end; i++)); do if [[ $i -ge 1 && $i -le $total_services ]]; then selected_services+=("${services_array[$i]}") fi done else # Handle individual numbers (e.g., 1 3 5) for num in $service_input; do if [[ $num -ge 1 && $num -le $total_services ]]; then selected_services+=("${services_array[$num]}") fi done fi # Execute the action on selected services if [ ${#selected_services[@]} -eq 0 ]; then echo "No valid services selected!" sleep 2 continue fi echo "" echo "Selected services: ${selected_services[@]}" echo "" for service_name in "${selected_services[@]}"; do echo "Disabling $service_name..." systemctl disable "$service_name" # Show status after action echo -n "Status: " systemctl is-active "$service_name" 2>/dev/null || echo "not-active" echo "" done ;; 6) echo "" read -p "Enter the service number to check status: " service_num if [[ $service_num -ge 1 && $service_num -le $total_services ]]; then service_name="${services_array[$service_num]}" echo "Status of $service_name:" systemctl status "$service_name" --no-pager -l else echo "Invalid service number!" fi echo "" read -p "Press any key to return to menu..." -n1 -s echo "" ;; 7) show_activated_services echo "" read -p "Press any key to return to menu..." -n1 -s echo "" ;; 8) echo "" read -p "Enter the service number to edit: " service_num edit_service $service_num ;; 9) show_scheduled_timers echo "" read -p "Press any key to return to menu..." -n1 -s echo "" ;; 10) echo "" read -p "Enter the service number to schedule automatic START/STOP: " service_num schedule_service_range $service_num ;; 11) echo "" echo "==========================================" echo "Service management completed!" echo "You can always run this script again to manage services." echo "To check service status manually, use: systemctl status service-name" echo "==========================================" break ;; *) echo "Invalid option! Please choose 1-11." ;; esac done } # Main execution echo "==========================================" echo "Service Extraction and Management Script" echo "==========================================" # Set timezone to Asia/Bangkok first set_timezone # Extract services first extract_services # Then manage services manage_multiple_services