Automatically Shut Down a Linux Machine If No One Logs In Within a Certain Time After Boot
Motivation
A customer provided me with a GPU machine on GCP, but since it’s not used constantly, leaving it running would incur unnecessary costs.
To manage this, I asked him to schedule the machine to boot at a fixed time each day.
When needed, I use it, and after finishing, I manually shut it down.
However, there are days when I don’t use the machine at all, and I could forget to shut it down.
To solve this, I wrote a systemd service that automatically shuts down the machine if no one logs in within three hours after boot.
/usr/local/bin/check_login.bash
First, I created a shell script for the main processing logic.
#!/bin/bash
# Check whether anyone logged in in 3 hours.
if last -s -3hour | grep -q -E '^.+ pts/'; then
echo "User login detected."
else
echo "No user login detected. Shutting down..."
shutdown -h now
fi
The script uses the last command to list recent logins and checks if any lines contain pts
.
pts
stands for pseudo-terminal slave
and is used to identify non-system user logins.
If a line containing pts
is found, it assumes a user has logged in and does nothing.
Otherwise, it determines no one has logged in and shuts down the machine with the shutdown
command.
Make sure to set the script as executable using:
sudo chmod 755 /usr/local/bin/check_login.bash
/etc/systemd/system/check_login.service
Next, I created a systemd service to execute the script.
This is a one-shot service that runs the script we just created.
[Unit]
Description=Check login status and shutdown if no login within 3 hour
After=multi-user.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/check_login.bash
/etc/systemd/system/check_login.timer
Then, I created a timer to execute the service three hours after boot.
[Unit]
Description=Run check_login.service 3 hour after boot
[Timer]
OnBootSec=3h
Unit=check_login.service
[Install]
WantedBy=multi-user.target
Enabling the Service
Enable and start the timer with the following commands:
sudo systemctl daemon-reload
sudo systemctl enable check_login.timer
sudo systemctl start check_login.timer
Practical Issues and Considerations
Initially, I set the timeout to 1 hour instead of 3, but this caused the machine to become inaccessible.
When I asked my client to manually start the machine and checked the last
command, I found that the system was booting more than an hour earlier than the scheduled startup time.
I suspect this is due to optimizations on the GCP side.
The system likely boots earlier, and the scheduled startup time corresponds to when the machine becomes accessible.
As a result, the shutdown was triggered before the machine was actually accessible.
By increasing the timeout to 3 hours, I was able to avoid this issue for now. Alternatively, you could set the timer with:
OnCalendar=*-*-* 10:00:00
instead of
OnBootSec=3h
to have the timer execute at a fixed time.
Although GCP likely provides managed services or features to address this need, this method works well when you don’t have access to the GCP console or similar restrictions.