#!/bin/bash # sdtimeout.sh - Interactively set systemd stop job timeout SYSTEM_CONF="/etc/systemd/system.conf" USER_CONF="/etc/systemd/user.conf" SETTING="DefaultTimeoutStopSec" # Colors LRED="\033[1;31m" LGREEN="\033[1;32m" YELLOW="\033[1;33m" LCYAN="\033[1;36m" BWHITE="\e[1m" NC='\033[0m' prompt_seconds() { local label="$1" local result_var="$2" local val while true; do echo -e -n "\n${YELLOW}${label}${NC}" read val if [ -z "${val}" ]; then echo -e "${LRED}Please enter a value.${NC}" continue fi if [[ ! "${val}" =~ ^[0-9]+$ ]]; then echo -e "${LRED}'${val}' is not a valid number of seconds.${NC}" continue fi if [ "${val}" -lt 1 ]; then echo -e "${LRED}Value must be at least 1 second.${NC}" continue fi eval "${result_var}=${val}" break done } set_timeout_in_file() { local file="$1" local seconds="$2" local new_line="${SETTING}=${seconds}s" if grep -qE "^#?[[:space:]]*${SETTING}=" "${file}" 2>/dev/null; then sudo sed -i "s|^#\?[[:space:]]*${SETTING}=.*|${new_line}|" "${file}" else echo -e "\n[Manager]" | sudo tee -a "${file}" > /dev/null echo "${new_line}" | sudo tee -a "${file}" > /dev/null fi } verify_file() { local file="$1" local seconds="$2" local match match=$(grep -E "^${SETTING}=${seconds}s" "${file}" 2>/dev/null) if [ -z "${match}" ]; then echo -e "${LRED}Verification failed: '${SETTING}=${seconds}s' not found in ${file}${NC}" return 1 fi return 0 } show_snippet() { local file="$1" local seconds="$2" echo -e "\n${LCYAN}--- ${file} (context around change) ---${NC}" grep -n -E "${SETTING}" "${file}" } # --- Main --- echo -e "\n${BWHITE}systemd Stop Job Timeout Configurator${NC}" echo -e "${LCYAN}--------------------------------------${NC}" echo -e "This script sets ${BWHITE}${SETTING}${NC} in:" echo -e " ${SYSTEM_CONF}" echo -e " ${USER_CONF}\n" prompt_seconds "System-wide stop job timeout in seconds (e.g. 90): " system_secs prompt_seconds "User-scope stop job timeout in seconds (e.g. 90): " user_secs echo -e "\n${YELLOW}System timeout will be set to: ${LGREEN}${system_secs}s${NC}" echo -e "${YELLOW}User timeout will be set to: ${LGREEN}${user_secs}s${NC}" echo -e "\n${YELLOW}Your password is required to edit systemd config files.${NC}" echo -e "${YELLOW}Press Enter to continue or Ctrl+C to cancel.${NC}" read # Verify sudo works before proceeding sudo -v if [ $? -ne 0 ]; then echo -e "\n${LRED}Authentication failed. Exiting.${NC}\n" exit 1 fi echo -e "\n${LCYAN}Applying changes...${NC}" set_timeout_in_file "${SYSTEM_CONF}" "${system_secs}" set_timeout_in_file "${USER_CONF}" "${user_secs}" echo -e "\n${LCYAN}Verifying changes...${NC}" errors=0 verify_file "${SYSTEM_CONF}" "${system_secs}" [ $? -ne 0 ] && errors=$((errors + 1)) verify_file "${USER_CONF}" "${user_secs}" [ $? -ne 0 ] && errors=$((errors + 1)) echo -e "\n${LCYAN}Checking systemd can parse the config...${NC}" systemd-analyze cat-config systemd/system.conf > /dev/null 2>&1 if [ $? -ne 0 ]; then echo -e "${LRED}systemd-analyze reported an issue reading system.conf — please inspect manually.${NC}" errors=$((errors + 1)) else echo -e "${LGREEN}system.conf parsed OK by systemd.${NC}" fi systemd-analyze cat-config systemd/user.conf > /dev/null 2>&1 if [ $? -ne 0 ]; then echo -e "${LRED}systemd-analyze reported an issue reading user.conf — please inspect manually.${NC}" errors=$((errors + 1)) else echo -e "${LGREEN}user.conf parsed OK by systemd.${NC}" fi if [ "${errors}" -gt 0 ]; then echo -e "\n${LRED}One or more changes could not be verified. Please check the files manually.${NC}\n" exit 1 fi echo -e "\n${LGREEN}All changes applied and verified successfully!${NC}" show_snippet "${SYSTEM_CONF}" "${system_secs}" show_snippet "${USER_CONF}" "${user_secs}" echo -e "\n${LCYAN}Changes will take effect after the next reboot or:${NC}" echo -e " ${BWHITE}sudo systemctl daemon-reexec${NC}\n"