Auto-Shutdown Script for Linux (Bash) with VLC State Check

Even though favorite Linux distributions (such as BackBox Linux or XFCE environments) offer exceptional stability and performance, a common annoyance arises when streaming media players like VLC prevent the system from entering idle power-saving or auto-shutdown modes. For anyone who falls asleep while watching a favorite series or movie, waking up to find the laptop or PC running the entire night becomes a recurring issue.

Auto-Shutdown Script for Linux (Bash) with VLC State Check

This Bash automation script solves the problem by monitoring user inactivity (xprintidle) while checking whether VLC is actively playing media via MPRIS DBUS. If the user is idle and VLC is paused or closed, the script initiates a graceful countdown before triggering a system shutdown.

Purpose & Features

  • Idle Tracking: Measures system inactivity using xprintidle to prevent abrupt shutdowns while you are working.
  • VLC Awareness: Interrogates the MPRIS DBUS interface to check if VLC is currently playing. If media playback is active, shutdown is bypassed.
  • Safety Countdown: Sends a desktop notification (notify-send) and waits 60 seconds before powering off, allowing a final check for activity.
  • Debug Logging: Includes comprehensive set -x and echo logging to track execution states seamlessly.

Usage & Execution

Since the script is not configured for autostart on system boot, you grant execution permissions once and launch it before heading off to sleep with VLC.

  1. Make the script executable (run once):

Bash:

touch shut_me_down.sh

chmod +x shut_me_down.sh

Run the script before going to sleep: Launch the script in your terminal prior to starting media playback:

Bash:

shut_me_down.sh

Disclaimer

Disclaimer: This script executes sudo poweroff when triggered. Ensure that your user account has passwordless sudo privileges configured for the poweroff command (or adjust the shutdown command to suit your system setup), otherwise the final shutdown step will hang waiting for a password prompt in the background. Use at your own risk.

Code:

#!/bin/bash
# Author: Relic Perisa 🔻(С)
# Domain: perisareljic.name

# Enable command tracing for verification
set -x

# Explicitly set paths and screen display
export DISPLAY=:0
export PATH=$PATH:/usr/bin:/usr/sbin:/sbin

# Dynamically locate the user's DBUS address (required for background VLC checks)
USER_ID=$(id -u)
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$USER_ID/bus"

IDLE_TIME_LIMIT=420000 # 420 seconds (7 minutes)
CHECK_INTERVAL=10      # Check every 10 seconds

echo "DEBUG: Script started..."

while true; do
    # Check idle time
    CURRENT_IDLE=$(xprintidle 2>/dev/null)
    
    # If xprintidle fails or is missing, log error
    if [ -z "$CURRENT_IDLE" ]; then
        echo "ERROR: xprintidle is not installed or cannot access the display!"
        sleep 10
        continue
    fi

    echo "DEBUG: Current inactivity: $CURRENT_IDLE ms"

    if [ "$CURRENT_IDLE" -gt "$IDLE_TIME_LIMIT" ]; then
        echo "DEBUG: Time limit reached, checking VLC status..."
        
        # Check VLC status (MPRIS via DBUS)
        VLC_STATUS=$(dbus-send --print-reply --dest=org.mpris.MediaPlayer2.vlc /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:'org.mpris.MediaPlayer2.Player' string:'PlaybackStatus' 2>/dev/null | grep -Po '(?<=")\w+(?=")')
        
        echo "DEBUG: VLC status is: [$VLC_STATUS]"

        if [ "$VLC_STATUS" = "Playing" ]; then
            echo "DEBUG: VLC is still playing media. Skipping shutdown."
        else
            echo "DEBUG: VLC is closed or paused. Initiating shutdown sequence!"
            notify-send "System Inactive" "Shutting down in 60s..."
            
            sleep 60
            
            # Final check before powering off
            FINAL_IDLE=$(xprintidle)
            if [ "$FINAL_IDLE" -gt 60000 ]; then
                echo "DEBUG: EXECUTING SHUTDOWN!"
                sudo poweroff
            else
                echo "DEBUG: Activity detected at the last moment, aborting."
            fi
        fi
    fi
    sleep $CHECK_INTERVAL
done

The complete source code is available on my GitHub repository