How to Verify the Scripts in /lib/systemd/system-shutdown are Being Run

Abstract: Verify scripts in /lib/systemd/system-shutdown by checking journalctl -b -1 logs for execution evidence and exit codes.

Created: 2026-08-31 by

Scripts in /lib/systemd/system-shutdown execute during the final stages of system shutdown, after all services have stopped. To verify they are running, check the journal logs for specific exit codes using systemctl status, inspect the /run/systemd/shutdown directory for temporary files created by your scripts, and use journalctl -b -1 to review logs from the previous boot cycle where these shutdown events occurred.

Understanding the Shutdown Sequence

The systemd initialization system manages the lifecycle of processes on Linux systems. When you initiate a shutdown, systemd does not simply kill all processes; it follows a structured sequence designed to ensure data integrity and proper resource release. The directory /lib/systemd/system-shutdown contains scripts that are intended to run after the main system has entered the shutdown target but before the kernel actually halts or reboots. These scripts operate in a minimal environment where many standard utilities might be unavailable or behave differently because the root filesystem may be mounted read-only or unmounted entirely depending on the timing. It is crucial to understand that these scripts are executed synchronously. If a script hangs or waits for user input, the system will hang indefinitely during shutdown. This behavior makes verification critical, as a failing script can appear as if the system itself is frozen rather than the script being the culprit. The scripts must be executable and typically should return an exit code of zero to indicate success. Any non-zero exit code is logged, but systemd generally continues with the shutdown process unless the script explicitly causes a fatal error in the shutdown manager itself. For more context on how systemd handles service ordering during complex transitions, you might find it helpful to read about preserving order of closing services while shutting down Linux. This knowledge helps in understanding why your script might be placed where it is in the execution timeline relative to other system components.

Checking Journal Logs for Execution Evidence

The most reliable way to confirm that a script in /lib/systemd/system-shutdown ran is to examine the system journal. Because the system is shutting down, the current journal session ends abruptly. Therefore, you cannot always see the output in real-time on the screen that displays the shutdown messages. Instead, you must look at the logs from the previous boot cycle. To do this, reboot the system and then open a terminal. Use the command journalctl -b -1 to view logs from the previous boot. The -b flag specifies the boot ID, and -1 refers to the boot immediately preceding the current one. You can filter these logs for your specific script name or for the general shutdown target. Look for entries related to systemd-shutdown or the specific name of your script. If your script produces output via echo or logger, those messages will appear in the journal under the context of the shutdown process. For example, if you have a script named my-cleanup.sh, searching for "my-cleanup" in the previous boot's journal will show if it was invoked. Additionally, checking the exit status is vital. Systemd logs the exit status of each unit. If your script failed, you will see a line indicating a failure with a non-zero exit code. Another useful diagnostic step is to use journalctl -t systemd-shutdown. This filters the log to show only messages generated by the shutdown manager itself. While this might not show every detail of your custom script, it confirms that the shutdown phase was reached and processed. If you suspect race conditions or issues with subprocesses, reviewing articles on binary vs shell systemd subprocess issues can provide deeper insight into how different execution contexts behave during these low-level operations.

Using Logger for Persistent Messages

Standard output from scripts in this directory might be lost if the logging daemon shuts down before your script runs. To ensure your messages persist, use the logger command within your script. For instance, adding logger -t my-script "Starting cleanup" ensures that the message is sent to the syslog/journal regardless of whether stdout is still connected to a terminal. This technique is particularly effective for debugging because it creates a distinct tag in the journal, making it easy to grep for later.

Creating Temporary Files for Verification

Sometimes, journal access is limited, or you want a physical confirmation that the script executed. A simple and robust method is to create a temporary file in a location that persists across reboots, such as /tmp or a dedicated directory like /var/log/shutdown-checks. Inside your script, add a command like touch /tmp/script-executed-$(date +%s). After the system shuts down and restarts, check if the file exists. The presence of the file proves that the script ran. Using a timestamp in the filename prevents overwriting and allows you to correlate the file creation time with the shutdown event. This method is foolproof because it relies on the filesystem state rather than volatile memory logs. However, be aware that if the root filesystem is remounted read-only before your script runs, you may need to write to a tmpfs mount that is guaranteed to be available, or use /dev/shm if accessible.

Debugging Common Failures

Scripts in /lib/systemd/system-shutdown often fail due to missing dependencies or incorrect permissions. Ensure the script has the executable bit set using chmod +x /lib/systemd/system-shutdown/your-script.sh. Also, verify that any commands called within the script are available in the minimal environment provided during shutdown. For example, some network tools might not be loaded yet, or paths might differ. If your script depends on other services stopping first, ensure there are no circular dependencies or timeouts causing premature termination. Checking custom systemd timers or service failures can sometimes reveal broader configuration issues that affect shutdown reliability. If you encounter baffling differences between executing binaries versus shell scripts, refer to guides on subprocess issues to understand environment variable inheritance and path resolution differences. Finally, remember that changes to scripts in /lib/systemd/system-shutdown take effect immediately on the next shutdown; no daemon reload is required. However, if you move scripts to /etc/systemd/system-shutdown, which overrides the default directory, you must ensure the override directory exists and is properly configured. Always test in a safe environment where data loss is acceptable, as improper shutdown scripts can lead to filesystem corruption.

Frequently Asked Questions

Why can't I see the output of my shutdown script on the screen?

The display console often switches to a lower priority or disconnects before your script executes. Systemd redirects standard output to the journal, so you must check journalctl instead of relying on visual feedback. This design prevents screen clutter during the critical final moments of shutdown.

What happens if my shutdown script exits with a non-zero code?

Systemd logs the failure but typically continues the shutdown process unless the script triggers a critical error condition. It is best practice to ensure your script exits with code 0 to indicate successful completion. Non-zero codes are recorded in the journal for troubleshooting purposes.

Can I use network commands in a system-shutdown script?

Generally, no. By the time system-shutdown scripts run, network interfaces are usually brought down and network services are stopped. Attempting to use network commands may result in errors because the necessary daemons are no longer active. Stick to local filesystem operations or pre-configured connections.

How do I prevent my script from hanging the system?

Avoid any commands that require user interaction or wait indefinitely for external resources. Use timeouts for any potentially blocking operations, such as waiting for a device to respond. Testing your script manually in a simulated shutdown environment can help identify potential hangs before deploying them to production.

Is it better to store scripts in /lib or /etc for shutdown tasks?

Scripts in /lib/systemd/system-shutdown are part of the system package and may be overwritten during updates. Storing custom scripts in /etc/systemd/system-shutdown is recommended as it persists across updates and takes precedence. This separation ensures your custom logic remains intact even when system packages are upgraded.

Latest News

How to Display Output of xterm Command in Terminal Screen using Cron

Resolve the inability to display xterm output in a terminal screen from cron by redirecting logs or using wall instead of insecure X11 workarounds.

Read More
Expose Local Server on VPS Preserving Real Client IPs (OS Level)

Resolve VPS logging showing only gateway IPs by configuring reverse proxies to forward real client addresses via X-Forwarded-For headers.

Read More
How to Clear Recent Files History in Linux without Deleting Actual Files?

Clear recent files history in Linux by deleting ~/.local/share/recently-used.xbel without removing the actual files.

Read More
Best HDD Copy Strategy: Manually Syncing and Rewriting Scratch

Resolve data drift between two 4TB hard drives by using rsync with the --delete flag to manually sync and rewrite scratch data for an exact mirror.

Read More
Understanding Bash Prompt Abbreviations: An Overview

Resolve repetitive typing errors by creating and persisting Bash aliases in the .bashrc file for improved command-line efficiency.

Read More
Free Tools and Methods to Log Real-Time Performance Details in Task Manager

Log real-time CPU and memory metrics to CSV files using Windows Performance Monitor Data Collector Sets to troubleshoot system slowness.

Read More
Contact Qatar Airways Customer Service: Phone Number, Help Center, and More

Resolve urgent Qatar Airways reservation issues like flight changes and baggage claims using the US phone number +1801-855-5905 or online self-service tools.

Read More
Windows 11: Alt Codes Displaying Wrong Characters - Solutions

Resolve Windows 11 Alt codes showing wrong characters by verifying the US keyboard layout and enabling Num Lock.

Read More
Run Programs with Elevated Privileges: A Comprehensive Guide

Eliminates the need to type sudo for frequent administrative tasks by configuring .bashrc aliases or functions.

Read More
Dynamically Changing Dates in Excel Formulas Using Cells

Eliminate manual date updates in Excel by using cell references to create dynamic formulas that automatically adjust calculations when input dates change.

Read More
Granting Edit Access to a Specific Excel Sheet in an Office 365 User Email ID-Based Login

Excel Online lacks native sheet-level permissions, so users must split workbooks or use worksheet protection to isolate edit access for specific tabs.

Read More
Creating Network Load on Local Wi-Fi from One PC

Generate sustained Wi-Fi bandwidth load from a single PC using a VM SFTP server to test router stability and throughput.

Read More
Changing the Default Editor for Batch Files in Windows 11's File Explorer

Resolve the issue of batch files opening in Notepad by changing the default editor to a preferred application like VS Code.

Read More
Gain WiFi Connection Minutes Before Losing it by Changing MAC Address

Bypass MAC address filtering to restore WiFi connectivity temporarily when a device is blocked by network administrators.

Read More
Photos Folders Turned Black: Troubleshooting Picture Applications on Windows

Resolve black screens in Windows Photos by resetting the app, updating graphics drivers, and repairing system files.

Read More
Troubleshooting High CPU Temperature Values: A Step-by-Step Guide

Resolve high CPU temperatures and thermal throttling by monitoring with Speedfan, cleaning dust from cooling components, and replacing degraded thermal paste.

Read More
Make cURL establish TLS connection with CA unknown

Resolve cURL TLS connection failures with unknown or self-signed certificates by using the --insecure flag to bypass CA validation.

Read More
Troubleshooting Incorrect Network Metrics Values in Grafana, Prometheus, InfluxDB, and Telegraf

Fix incorrect network metrics in Grafana, Prometheus, InfluxDB, and Telegraf by verifying interface selection, resolving unit mismatches, and handling counter resets.

Read More
Start Another Terminal Window (cmd.exe) Windows Repair/Troubleshoot

Provides step-by-step instructions to access the Windows Command Prompt via bootable media for advanced system repair and troubleshooting.

Read More
Thinkpad P1 Gen 6: Sudden Thunderbolt 3 Dock USB-C Charging Stopped Working

Resolve sudden Thunderbolt 3 dock USB-C charging and internet failure on ThinkPad P1 Gen 6 by updating firmware, resetting the dock, and adjusting power settings.

Read More
ASUS Windows 11 Laptop: Internet Connection Issue with Hotspot

Resolve ASUS Windows 11 laptop spinning wheel issue when connecting to mobile hotspot by resetting network stack, disabling IPv6, and adjusting power settings.

Read More
Developing iOS Project with Firebase: Logging in and Sending Push Notifications

Integrates Firebase to enable secure user authentication and push notifications in iOS applications.

Read More
Troubleshooting Bash Script with Suspected Issues of Spaces, Dashes, Filenames and Quoting

Resolve Bash script failures caused by word splitting, globbing, and special characters in filenames by applying proper quoting techniques.

Read More
Populating OneDrive Folder for Local Backup without Affecting Remote Files

Prevent OneDrive from deleting remote files during Windows reinstallation by unlinking the account or using symbolic links to isolate local data.

Read More
Force First Frame as Keyframe Without Re-encoding: A Quick Solution

Resolve inaccurate seeking and playback glitches by re-encoding video to ensure the first frame is a valid keyframe.

Read More
Find Information in Database Using WSL (Ubuntu) on Windows-10

Resolve database connection issues from WSL Ubuntu on Windows 10 by configuring client tools and network access to query remote or local servers.

Read More
Configuring a New Router with Different Networks: One Family, One Guest

Resolve IP conflicts and isolate guest traffic by configuring a second router with a distinct subnet via its WAN port.

Read More
Quickly Open Multiple Stock Websites with a Single Command

Solve the problem of manually opening multiple stock research websites by creating a single command to launch them simultaneously on Windows, macOS, or Linux.

Read More
Improved Adobe Acrobat Search Experience: Access Advanced Search with Ease

Access advanced search filters like case sensitivity and regex in Adobe Acrobat by clicking More Options in the Find bar.

Read More
Port Forwarding VM via OpenVPN: A Comprehensive Guide

Configure OpenVPN server and iptables to forward specific ports from VPN clients to a virtual machine's internal IP address.

Read More
Understanding Partitions in the 1980s: A Look Back at MS-DOS and Master Boot Record

Explains how the Master Boot Record and partition table enabled MS-DOS to manage multiple disk volumes on a single physical drive.

Read More
Windows 10 Enterprise: Keyboard Not Detected in Managed Organization with Admin Privileges

Resolve Windows 10 Enterprise keyboard detection failures caused by Group Policy restrictions, driver corruption, or USB enumeration errors.

Read More
Can't Find x86_64 Versions of Applications on MacOS arm64 (M1)

Resolve missing x86_64 app issues on M1 Macs by installing Rosetta 2 and reinstalling apps as universal binaries.

Read More
How to Hide Installation Source for an Android App

Manage Android app installation source visibility by using USB transfers or file managers to reduce browser traces and isolate data via work profiles.

Read More
Connecting Momentus 4200.2 ST9808210A Hard Drive via USB Cable

Resolve inability to access Seagate Momentus 4200.2 ST9808210A hard drive by connecting it via USB using a compatible SATA-to-USB adapter and configuring the disk in Windows.

Read More