diff --git a/sdtimeout.sh b/sdtimeout.sh new file mode 100755 index 0000000..ec92c87 --- /dev/null +++ b/sdtimeout.sh @@ -0,0 +1,153 @@ +#!/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"