systemd-inhibit wraps one command in a temporary lock so a sleep, shutdown or idle timer cannot cut it off halfway through. That matters for the job that should never be interrupted: writing removable media, finishing a long export, the thing you find out failed only after the laptop lid closed itself. The examples use systemd 255.4-1ubuntu8.17 from the systemd package.
Allow about ten minutes. You need a shell, the systemd-inhibit command and a working user session connected to systemd-logind. The command does not make a permanent configuration change: it acquires a lock before starting the child process and releases it when that process exits.
Confirm the version and review the available operation names:
$ systemd-inhibit --version
systemd 255 (255.4-1ubuntu8.17)
$ systemd-inhibit --help
systemd-inhibit [OPTIONS...] COMMAND ...
Your version string may differ. The local manpage describes shutdown, sleep and idle, plus the lower-level key and lid handlers. Do not assume an option from a different systemd release is available here.
Checkpoint: If the command is missing, install or enable the package using your distribution's normal package process. Do not substitute an unrelated desktop power-management command.
Put systemd-inhibit before the command that must finish. This example protects a one-second test process:
$ systemd-inhibit \
--what=shutdown:sleep:idle \
--who='media export' \
--why='finishing the export' \
sleep 1
idle:sleep:shutdown; supplying it explicitly makes the safety boundary visible during review.The lock exists only while the child is running.
Safety boundary: An inhibitor is not a backup, a transaction or a guarantee that hardware will stay powered. It does not prevent a forced power cut, a kernel failure or every possible administrative action. Keep the protected operation bounded and give it its own recovery plan.
A practical pattern is to protect a command that already has a clear input and output. This example writes a new archive and leaves the original directory untouched:
set -e
systemd-inhibit \
--what=sleep:shutdown \
--who='nightly archive' \
--why='writing the archive' \
tar -czf /path/to/new-archive.tar.gz /path/to/source-directory
Replace both paths with real paths before running it, and check free space first because the output archive can be large. Do not point the output at an existing important archive unless overwriting it is deliberate and recoverable.
systemd-inhibit returns the exit status of the executed program, so a successful wrapper status means tar succeeded, not that the source now matches your wider retention policy. In a shell script, capture or test the wrapper's status immediately, before another command changes $?.
Checkpoint: Try a harmless sleep 1 first. If the wrapper reports Failed to inhibit: Access denied, the session cannot acquire this lock. Do not hide that error with || true; investigate the session and logind policy, or decide the operation must stop when protection is unavailable. Elevated privileges are not a normal prerequisite, and sudo may just change which session can create the lock rather than fix the underlying policy.
Use --list to list active locks instead of starting a child command:
$ systemd-inhibit --no-pager --no-legend --list
ModemManager 0 root 2496533 ModemManager sleep ModemManager needs to reset devices delay
NetworkManager 0 root 996 NetworkManager sleep NetworkManager needs to turn off networks delay
UPower 0 root 3157839 upowerd sleep Pause device polling delay
The exact rows depend on the machine and change as services start or stop. The columns identify the user ID, process ID, program, inhibited operation, reason and mode. Output may be paged unless you pass --no-pager; --no-legend removes headings and the footer, which suits scripts, but do not parse this human-readable layout as a stable machine interface without testing it against your systemd version.
A lock belonging to a process that has already exited should disappear on its own. If a lock remains while a long-running operation is active, find that process and let it finish normally. Killing it releases the lock but can leave its work incomplete, so use the application's own cancellation and recovery procedure first.
The default mode is block. It prohibits the requested operations without a time limit, and only privileged users may override it. Use it when an operation must either finish or be stopped by an administrator who understands the consequences.
--mode=delay asks logind to delay a sleep or shutdown only for a limited period, set in logind.conf. The manpage restricts delay mode to sleep and shutdown; it does not apply to idle or the key and lid handler operations.
$ systemd-inhibit \
--what=sleep:shutdown \
--mode=delay \
--who='short export' \
--why='allowing the export to finish' \
/path/to/export-command
Do not pick delay mode merely because it sounds less intrusive. A long export can outlive the configured limit and get interrupted anyway. If you need an unbounded lock, use the default block mode and make the command's duration and cancellation behaviour clear to the people operating the machine.
systemd-inhibit on one line and the real command on a later line; the lock belongs to the child process, not to your shell.--what only when that low-level behaviour is genuinely required.There is no persistent lock file to delete and no undo command to run. Recovery is simply letting the child exit, or stopping it through its documented cancellation path. Once it exits, run systemd-inhibit --no-pager --no-legend --list again if you need to confirm the transient lock has gone.
block or delay with its time limit and scope understood.