feat: made midnight shutdown more restrictive

This commit is contained in:
Krzysztof kuhy Rudnicki 2025-07-23 16:27:24 +02:00
parent 61c1494e2e
commit 59b1c21b46

View File

@ -1,21 +1,26 @@
#!/bin/bash
# Script to set up automatic PC shutdown at midnight on Arch Linux
# Creates systemd timer and service for daily shutdown at 00:00
# Script to set up automatic PC shutdown with day-specific time windows
# Saturday-Thursday: Shutdown between 21:30-05:00
# Friday/Sunday: Shutdown between 00:00-05:00
# Handles sudo privileges automatically
set -e # Exit on any error
# Function to show usage
show_usage() {
echo "Midnight Auto-Shutdown Setup for Arch Linux"
echo "==========================================="
echo "Day-Specific Auto-Shutdown Setup for Arch Linux"
echo "==============================================="
echo "Usage: $0 [enable|disable|status]"
echo ""
echo "Commands:"
echo " enable - Set up automatic midnight shutdown (default)"
echo " disable - Remove automatic midnight shutdown"
echo " enable - Set up automatic shutdown with day-specific windows (default)"
echo " disable - Remove automatic shutdown"
echo " status - Show current status"
echo ""
echo "Shutdown Schedule:"
echo " Saturday-Thursday: 21:30-05:00"
echo " Friday/Sunday: 00:00-05:00"
echo ""
}
# Function to check and request sudo privileges
@ -38,27 +43,28 @@ fi
# Function to disable and remove midnight shutdown
disable_midnight_shutdown() {
echo "Disabling Midnight Auto-Shutdown"
echo "==============================="
echo "Disabling Day-Specific Auto-Shutdown"
echo "===================================="
echo "Current Date: $(date)"
echo "User: $ACTUAL_USER"
echo ""
local timer_file="/etc/systemd/system/midnight-shutdown.timer"
local service_file="/etc/systemd/system/midnight-shutdown.service"
local script_file="/usr/local/bin/midnight-shutdown-manager.sh"
local timer_file="/etc/systemd/system/day-specific-shutdown.timer"
local service_file="/etc/systemd/system/day-specific-shutdown.service"
local script_file="/usr/local/bin/day-specific-shutdown-manager.sh"
local check_script="/usr/local/bin/day-specific-shutdown-check.sh"
local removed_files=()
# Stop and disable timer if it exists
if systemctl is-active midnight-shutdown.timer &>/dev/null; then
echo "Stopping midnight-shutdown timer..."
systemctl stop midnight-shutdown.timer
if systemctl is-active day-specific-shutdown.timer &>/dev/null; then
echo "Stopping day-specific-shutdown timer..."
systemctl stop day-specific-shutdown.timer
echo "✓ Timer stopped"
fi
if systemctl is-enabled midnight-shutdown.timer &>/dev/null; then
echo "Disabling midnight-shutdown timer..."
systemctl disable midnight-shutdown.timer
if systemctl is-enabled day-specific-shutdown.timer &>/dev/null; then
echo "Disabling day-specific-shutdown timer..."
systemctl disable day-specific-shutdown.timer
echo "✓ Timer disabled"
fi
@ -83,6 +89,13 @@ disable_midnight_shutdown() {
echo "✓ Removed management script: $script_file"
fi
# Remove check script
if [[ -f "$check_script" ]]; then
rm -f "$check_script"
removed_files+=("$check_script")
echo "✓ Removed check script: $check_script"
fi
# Reload systemd daemon
if [[ ${#removed_files[@]} -gt 0 ]]; then
echo "Reloading systemd daemon..."
@ -91,18 +104,18 @@ disable_midnight_shutdown() {
fi
echo ""
echo "=========================================="
echo "Midnight Auto-Shutdown Removal Complete"
echo "=========================================="
echo "============================================="
echo "Day-Specific Auto-Shutdown Removal Complete"
echo "============================================="
if [[ ${#removed_files[@]} -gt 0 ]]; then
echo "Removed files:"
printf " %s\n" "${removed_files[@]}"
echo ""
echo "✓ Automatic midnight shutdown has been completely disabled"
echo "✓ Your PC will no longer shutdown automatically at midnight"
echo "✓ Automatic day-specific shutdown has been completely disabled"
echo "✓ Your PC will no longer shutdown automatically"
else
echo "No midnight shutdown configuration was found to remove."
echo "No day-specific shutdown configuration was found to remove."
fi
echo ""
@ -110,8 +123,8 @@ disable_midnight_shutdown() {
# Function to show current status
show_current_status() {
echo "Midnight Auto-Shutdown Status"
echo "============================"
echo "Day-Specific Auto-Shutdown Status"
echo "================================="
echo "Current Date: $(date)"
echo "User: $ACTUAL_USER"
echo ""
@ -121,21 +134,21 @@ show_current_status() {
local script_exists=false
# Check if files exist
if [[ -f "/etc/systemd/system/midnight-shutdown.timer" ]]; then
if [[ -f "/etc/systemd/system/day-specific-shutdown.timer" ]]; then
timer_exists=true
echo "✓ Timer file exists"
else
echo "✗ Timer file missing"
fi
if [[ -f "/etc/systemd/system/midnight-shutdown.service" ]]; then
if [[ -f "/etc/systemd/system/day-specific-shutdown.service" ]]; then
service_exists=true
echo "✓ Service file exists"
else
echo "✗ Service file missing"
fi
if [[ -f "/usr/local/bin/midnight-shutdown-manager.sh" ]]; then
if [[ -f "/usr/local/bin/day-specific-shutdown-manager.sh" ]]; then
script_exists=true
echo "✓ Management script exists"
else
@ -146,13 +159,13 @@ show_current_status() {
# Check systemd status
if $timer_exists; then
if systemctl is-enabled midnight-shutdown.timer &>/dev/null; then
if systemctl is-enabled day-specific-shutdown.timer &>/dev/null; then
echo "✓ Timer is enabled"
if systemctl is-active midnight-shutdown.timer &>/dev/null; then
if systemctl is-active day-specific-shutdown.timer &>/dev/null; then
echo "✓ Timer is active"
echo ""
echo "Next scheduled shutdown:"
systemctl list-timers midnight-shutdown.timer --no-pager 2>/dev/null | grep midnight-shutdown || echo "Timer information not available"
echo "Next scheduled shutdown check:"
systemctl list-timers day-specific-shutdown.timer --no-pager 2>/dev/null | grep day-specific-shutdown || echo "Timer information not available"
else
echo "✗ Timer is not active"
fi
@ -164,6 +177,10 @@ show_current_status() {
fi
echo ""
echo "Shutdown Schedule:"
echo " Saturday-Thursday: 21:30-05:00"
echo " Friday/Sunday: 00:00-05:00"
echo ""
}
# Function to create the shutdown service
@ -172,17 +189,17 @@ create_shutdown_service() {
echo "1. Creating Systemd Shutdown Service..."
echo "======================================"
local service_file="/etc/systemd/system/midnight-shutdown.service"
local service_file="/etc/systemd/system/day-specific-shutdown.service"
cat > "$service_file" << 'EOF'
[Unit]
Description=Automatic PC shutdown at midnight
Description=Automatic PC shutdown with day-specific time windows
DefaultDependencies=false
Before=shutdown.target reboot.target halt.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/midnight-shutdown-check.sh
ExecStart=/usr/local/bin/day-specific-shutdown-check.sh
TimeoutStartSec=0
StandardOutput=journal
StandardError=journal
@ -197,15 +214,30 @@ create_shutdown_timer() {
echo "2. Creating Systemd Shutdown Timer..."
echo "==================================="
local timer_file="/etc/systemd/system/midnight-shutdown.timer"
local timer_file="/etc/systemd/system/day-specific-shutdown.timer"
cat > "$timer_file" << 'EOF'
[Unit]
Description=Timer for automatic PC shutdown at midnight
Requires=midnight-shutdown.service
Description=Timer for automatic PC shutdown with day-specific windows
Requires=day-specific-shutdown.service
[Timer]
OnCalendar=*-*-* 21:30:00
OnCalendar=*-*-* 22:00:00
OnCalendar=*-*-* 22:30:00
OnCalendar=*-*-* 23:00:00
OnCalendar=*-*-* 23:30:00
OnCalendar=*-*-* 00:00:00
OnCalendar=*-*-* 00:30:00
OnCalendar=*-*-* 01:00:00
OnCalendar=*-*-* 01:30:00
OnCalendar=*-*-* 02:00:00
OnCalendar=*-*-* 02:30:00
OnCalendar=*-*-* 03:00:00
OnCalendar=*-*-* 03:30:00
OnCalendar=*-*-* 04:00:00
OnCalendar=*-*-* 04:30:00
OnCalendar=*-*-* 05:00:00
Persistent=false
AccuracySec=1s
WakeSystem=false
@ -224,19 +256,19 @@ create_management_script() {
echo "3. Creating Management Script..."
echo "=============================="
local script_file="/usr/local/bin/midnight-shutdown-manager.sh"
local script_file="/usr/local/bin/day-specific-shutdown-manager.sh"
cat > "$script_file" << 'EOF'
#!/bin/bash
# Midnight Auto-Shutdown Manager
# Provides easy management of the midnight shutdown feature
# Day-Specific Auto-Shutdown Manager
# Provides easy management of the day-specific shutdown feature
TIMER_NAME="midnight-shutdown.timer"
SERVICE_NAME="midnight-shutdown.service"
TIMER_NAME="day-specific-shutdown.timer"
SERVICE_NAME="day-specific-shutdown.service"
show_status() {
echo "Midnight Auto-Shutdown Status"
echo "============================"
echo "Day-Specific Auto-Shutdown Status"
echo "================================="
if systemctl is-enabled "$TIMER_NAME" &>/dev/null; then
echo "Status: ENABLED"
@ -250,7 +282,12 @@ show_status() {
fi
echo ""
echo "Next scheduled shutdown:"
echo "Shutdown Schedule:"
echo " Saturday-Thursday: 21:30-05:00"
echo " Friday/Sunday: 00:00-05:00"
echo ""
echo "Next scheduled checks:"
systemctl list-timers "$TIMER_NAME" --no-pager 2>/dev/null | grep "$TIMER_NAME" || echo "Timer not active"
echo ""
@ -263,18 +300,22 @@ case "$1" in
show_status
;;
"logs")
echo "Midnight Auto-Shutdown Logs"
echo "=========================="
echo "Day-Specific Auto-Shutdown Logs"
echo "==============================="
journalctl -u "$SERVICE_NAME" --no-pager -n 20
;;
*)
echo "Midnight Auto-Shutdown Manager"
echo "Day-Specific Auto-Shutdown Manager"
echo "Usage: $0 {status|logs}"
echo ""
echo "Commands:"
echo " status - Show current status and next shutdown time"
echo " status - Show current status and next shutdown checks"
echo " logs - Show recent shutdown logs"
echo ""
echo "Shutdown Schedule:"
echo " Saturday-Thursday: 21:30-05:00"
echo " Friday/Sunday: 00:00-05:00"
echo ""
show_status
;;
esac
@ -290,29 +331,66 @@ create_shutdown_check_script() {
echo "4. Creating Smart Shutdown Check Script..."
echo "========================================"
local check_script="/usr/local/bin/midnight-shutdown-check.sh"
local check_script="/usr/local/bin/day-specific-shutdown-check.sh"
cat > "$check_script" << 'EOF'
#!/bin/bash
# Smart midnight shutdown check script
# Only shuts down if the current time is actually close to midnight
# Prevents shutdown on boot if system was off during scheduled time
# Smart day-specific shutdown check script
# Different shutdown windows based on day of week:
# Saturday-Thursday: 21:30-05:00
# Friday/Sunday: 00:00-05:00
# Get current time components
# Get current time and day
current_hour=$(date +%H)
current_minute=$(date +%M)
current_time_minutes=$((10#$current_hour * 60 + 10#$current_minute))
day_of_week=$(date +%u) # 1=Monday, 7=Sunday
day_name=$(date +%A)
# Midnight is 0 minutes (00:00)
# Allow shutdown if we're within 5 minutes of midnight
# This covers 23:55-00:05 range
if [[ $current_time_minutes -le 5 ]] || [[ $current_time_minutes -ge 1435 ]]; then
echo "$(date): Executing midnight shutdown - current time is within shutdown window"
logger -t midnight-shutdown "Executing scheduled shutdown at $(date)"
# Convert time to minutes for easier comparison
# 21:30 = 1290 minutes, 05:00 = 300 minutes
# 00:00 = 0 minutes, 05:00 = 300 minutes
logger -t day-specific-shutdown "Checking shutdown conditions at $(date) - Day: $day_name ($day_of_week), Time: $current_hour:$current_minute"
# Determine if we should shutdown based on day and time
should_shutdown=false
if [[ $day_of_week -eq 5 ]] || [[ $day_of_week -eq 7 ]]; then
# Friday (5) or Sunday (7): shutdown window 00:00-05:00
logger -t day-specific-shutdown "Today is $day_name - checking 00:00-05:00 window"
if [[ $current_time_minutes -ge 0 ]] && [[ $current_time_minutes -le 300 ]]; then
should_shutdown=true
logger -t day-specific-shutdown "Time $current_hour:$current_minute is within Friday/Sunday shutdown window (00:00-05:00)"
else
logger -t day-specific-shutdown "Time $current_hour:$current_minute is outside Friday/Sunday shutdown window (00:00-05:00)"
fi
else
# Monday(1), Tuesday(2), Wednesday(3), Thursday(4), Saturday(6): shutdown window 21:30-05:00
logger -t day-specific-shutdown "Today is $day_name - checking 21:30-05:00 window"
# Check if time is between 21:30 (1290 minutes) and 23:59 (1439 minutes)
# OR between 00:00 (0 minutes) and 05:00 (300 minutes)
if [[ $current_time_minutes -ge 1290 ]] || [[ $current_time_minutes -le 300 ]]; then
should_shutdown=true
if [[ $current_time_minutes -ge 1290 ]]; then
logger -t day-specific-shutdown "Time $current_hour:$current_minute is within evening shutdown window (21:30-23:59)"
else
logger -t day-specific-shutdown "Time $current_hour:$current_minute is within morning shutdown window (00:00-05:00)"
fi
else
logger -t day-specific-shutdown "Time $current_hour:$current_minute is outside shutdown window (21:30-05:00)"
fi
fi
if [[ $should_shutdown == true ]]; then
echo "$(date): Executing shutdown - current time $current_hour:$current_minute is within shutdown window for $day_name"
logger -t day-specific-shutdown "Executing scheduled shutdown at $(date)"
/usr/bin/systemctl poweroff
else
echo "$(date): Skipping shutdown - not within midnight window (current: $current_hour:$current_minute)"
logger -t midnight-shutdown "Skipped shutdown - not within midnight window (current: $current_hour:$current_minute)"
echo "$(date): Skipping shutdown - not within shutdown window for $day_name (current: $current_hour:$current_minute)"
logger -t day-specific-shutdown "Skipped shutdown - not within shutdown window for $day_name (current: $current_hour:$current_minute)"
fi
EOF
@ -331,12 +409,12 @@ enable_timer() {
echo "✓ Reloaded systemd daemon"
# Enable the timer
systemctl enable midnight-shutdown.timer
echo "✓ Enabled midnight-shutdown timer"
systemctl enable day-specific-shutdown.timer
echo "✓ Enabled day-specific-shutdown timer"
# Start the timer
systemctl start midnight-shutdown.timer
echo "✓ Started midnight-shutdown timer"
systemctl start day-specific-shutdown.timer
echo "✓ Started day-specific-shutdown timer"
}
# Function to test the setup
@ -346,13 +424,13 @@ test_setup() {
echo "=================="
echo "Service files:"
if [[ -f "/etc/systemd/system/midnight-shutdown.service" ]]; then
if [[ -f "/etc/systemd/system/day-specific-shutdown.service" ]]; then
echo "✓ Service file exists"
else
echo "✗ Service file missing"
fi
if [[ -f "/etc/systemd/system/midnight-shutdown.timer" ]]; then
if [[ -f "/etc/systemd/system/day-specific-shutdown.timer" ]]; then
echo "✓ Timer file exists"
else
echo "✗ Timer file missing"
@ -360,60 +438,71 @@ test_setup() {
echo ""
echo "Timer status:"
if systemctl is-enabled midnight-shutdown.timer &>/dev/null; then
if systemctl is-enabled day-specific-shutdown.timer &>/dev/null; then
echo "✓ Timer is enabled"
else
echo "✗ Timer is not enabled"
fi
if systemctl is-active midnight-shutdown.timer &>/dev/null; then
if systemctl is-active day-specific-shutdown.timer &>/dev/null; then
echo "✓ Timer is active"
else
echo "✗ Timer is not active"
fi
echo ""
echo "Next scheduled shutdown:"
systemctl list-timers midnight-shutdown.timer --no-pager 2>/dev/null | grep midnight-shutdown || echo "Timer information not available"
echo "Next scheduled checks:"
systemctl list-timers day-specific-shutdown.timer --no-pager 2>/dev/null | head -5 | grep day-specific-shutdown || echo "Timer information not available"
}
# Function to show final instructions
show_instructions() {
echo ""
echo "=========================================="
echo "Midnight Auto-Shutdown Setup Complete"
echo "=========================================="
echo "================================================="
echo "Day-Specific Auto-Shutdown Setup Complete"
echo "================================================="
echo "Summary:"
echo "✓ Systemd service created (/etc/systemd/system/midnight-shutdown.service)"
echo "✓ Systemd timer created (/etc/systemd/system/midnight-shutdown.timer)"
echo "✓ Management script created (/usr/local/bin/midnight-shutdown-manager.sh)"
echo "✓ Systemd service created (/etc/systemd/system/day-specific-shutdown.service)"
echo "✓ Systemd timer created (/etc/systemd/system/day-specific-shutdown.timer)"
echo "✓ Management script created (/usr/local/bin/day-specific-shutdown-manager.sh)"
echo "✓ Smart check script created (/usr/local/bin/day-specific-shutdown-check.sh)"
echo "✓ Timer enabled and started"
echo ""
echo "Your PC will now automatically shutdown at 00:00 (midnight) every day."
echo "Shutdown Schedule:"
echo " Saturday-Thursday: 21:30-05:00 (evening to early morning)"
echo " Friday/Sunday: 00:00-05:00 (midnight to early morning)"
echo ""
echo "Management commands:"
echo " sudo midnight-shutdown-manager.sh status - Check status"
echo " sudo midnight-shutdown-manager.sh logs - View shutdown logs"
echo " sudo day-specific-shutdown-manager.sh status - Check status"
echo " sudo day-specific-shutdown-manager.sh logs - View shutdown logs"
echo ""
echo "Next shutdown: Tonight at 00:00"
echo "How it works:"
echo "• Timer checks every 30 minutes during potential shutdown windows"
echo "• Smart logic determines shutdown eligibility based on day and time"
echo "• Prevents accidental shutdowns outside designated time windows"
echo ""
echo "WARNING: This will permanently shutdown your PC every night at midnight."
echo "Make sure to save your work before midnight!"
echo "WARNING: This will automatically shutdown your PC during designated hours."
echo "Make sure to save your work before the shutdown windows!"
echo ""
}
# Function to prompt for confirmation
confirm_setup() {
echo ""
echo "WARNING: Auto-Shutdown Confirmation"
echo "=================================="
echo "This will set up your PC to automatically shutdown every day at midnight (00:00)."
echo "WARNING: Day-Specific Auto-Shutdown Confirmation"
echo "==============================================="
echo "This will set up your PC to automatically shutdown during specific time windows."
echo ""
echo "Shutdown Schedule:"
echo " Saturday-Thursday: 21:30-05:00 (9:30 PM to 5:00 AM)"
echo " Friday/Sunday: 00:00-05:00 (Midnight to 5:00 AM)"
echo ""
echo "Important considerations:"
echo "- Any unsaved work will be lost"
echo "- Any unsaved work will be lost during shutdown windows"
echo "- Running processes will be terminated"
echo "- Downloads/uploads in progress will be interrupted"
echo "- You'll need to manually power on your PC each day"
echo "- Timer checks every 30 minutes during potential shutdown windows"
echo ""
read -p "Do you want to proceed? (y/N): " confirm
@ -432,14 +521,14 @@ confirm_setup() {
# Function to confirm disable
confirm_disable() {
echo ""
echo "Disable Auto-Shutdown Confirmation"
echo "================================="
echo "This will completely remove the automatic midnight shutdown configuration."
echo "Disable Day-Specific Auto-Shutdown Confirmation"
echo "==============================================="
echo "This will completely remove the automatic day-specific shutdown configuration."
echo ""
echo "After disabling:"
echo "- Your PC will no longer shutdown automatically at midnight"
echo "- Your PC will no longer shutdown automatically during any time windows"
echo "- All related systemd services and timers will be removed"
echo "- The management script will be deleted"
echo "- The management and check scripts will be deleted"
echo ""
read -p "Do you want to proceed with disabling? (y/N): " confirm
@ -457,8 +546,8 @@ confirm_disable() {
# Main execution flow for enable
enable_midnight_shutdown() {
echo "Midnight Auto-Shutdown Setup for Arch Linux"
echo "==========================================="
echo "Day-Specific Auto-Shutdown Setup for Arch Linux"
echo "==============================================="
echo "Current Date: $(date)"
echo "User: $ACTUAL_USER"
echo "Target user: $ACTUAL_USER"