Join the 85,000 open source advocates who receive our giveaway alerts and article roundups.
How to run commands at shutdown on Linux
How to run commands at shutdown on Linux

Opensource.com
Linux and Unix systems have long made it pretty easy to run a command on boot. Just add your command to /etc/rc.local
and away you go. But as it turns out, running a command on shutdown is a little more complicated.
Why would you want to run a command as the computer shuts down? Perhaps you want to de-register a machine or service from a database. Maybe you want to copy data from a volatile storage system to a permanent location. Want your computer to post "#RIP me!" on its Twitter account before it shuts down?
I should clarify at this point that I'm talking about so-called "one-shot" commands as opposed to stopping a daemon. It's tempting to think of them the same way, though. If you're familiar with SysVinit you might think, "Oh, I'll just create a kill script." For example, /etc/rc.d/rc3.d/K99runmycommandatshutdown
should get invoked when your system exits runlevel 3. After all, that's how the scripts in /etc/init.d/
get stopped.
That's a great guess, but it turns out that it's wrong. SysVinit does not blindly run the kill scripts. Instead, it looks for (on Red Hat 6) /var/lock/subsys/service_name
(where service_name
here would be runmycommandatshutdown
). So you have to get a little bit tricky and treat your script like a regular service. The script below gives an example:
#!/bin/sh
# chkconfig: 2345 20 80
# description: An example init script to run a command at shutdown
# runmycommandatshutdown runs a command at shutdown. Very creative.
LOCKFILE=/var/lock/subsys/
start(){
# Touch our lock file so that stopping will work correctly
touch ${LOCKFILE}
}
stop(){
# Remove our lock file
rm ${LOCKFILE}
# Run that command that we wanted to run
mycommand
}
case "$1" in
start) start;;
stop) stop;;
*)
echo $"Usage: $0 {start|stop}"
exit 1
esac
exit 0
After putting that script in /etc/init.d/runmycommandatshutdown
and enabling it with chkconfig on runmycommandatshutdown
, your command will be run at shutdown.
systemd
All of that is great, but what if you're running a distribution of Linux that uses systemd instead of SysVinit? Turns out, it's much simpler with systemd. All you have to do is put your script in /usr/lib/systemd/system-shutdown/
, which is handled by systemd-halt.service. Of course, if you need to manage dependencies in a particular order (e.g., you can't post a tweet if the network stack is down), then you can write a systemd service unit file. For example:
[Unit]
Description=Run mycommand at shutdown
Requires=network.target
DefaultDependencies=no
Before=shutdown.target reboot.target
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
ExecStop=mycommand
[Install]
WantedBy=multi-user.target
10 Comments
"Turns out, it's much simpler with systemd."
I dispute that - for years I've been running a script when my system shuts down that copies all files that have changed to an external disk. Getting systemd to wait until the job finishes before shutting down was a major headache. Supposedly, systemd honours rc.d scripts, but I couldn't get this to work.
I had someone say the same thing about systemd and its ability to wait for a process to end prior to completing shutdown.
Here's the solution, using systemd scripts:
http://hackerpublicradio.org/eps.php?id=2134
Thanks for expanding what I know about Linux. I want to get 'fstrim' to run once a week when I shut down. I've experimented with 'cron' and 'anacron' but I'm not sure it's happening. I guess i should check the logs to be sure.
ubuntu 16.04 it's automatically runs fstrim once a weak, ubuntu 14.04 lts only runs fstrims one a week on intel and Samsung ssd's unless you add a no vender check opion, to a line some where, if you go to youtube ad serch how collins, and click on his name you can watch a video where he talks a little bit abought Darrin and how to add the no venerchech option in ubuntu 14.04 lts, not to sure about other Linux distros though
In Slackware (sysvinit in BSD compatible mode) it's even easier :)
$ cat /etc/rc.d/rc.local_shutdown
#!/bin/sh
#
# /etc/rc.d/rc.local_shutdown: Local system shutdown script.
#
# Put any local shutdown commands in here.
my_command_at_shutdown
exit 0
$ sudo chmod +x /etc/rc.d/rc.local_shutdown
I miss the days when shutdown used to be a script that could be edited. We ran Informix. We'd give a long period of grace, say 15 minutes, to the users. That gave them time to finish up what they were doing but there'd always be one who'd keep working up to the wire & get in the way of the final shutdown. Informix has a mode where it can continue processing on existing connections but inhibits the creation of new ones so I just put the command to enter that mode into the shutdown script alongside the wall that sent out the first warning message. It was more flexible way of doing things than relying on the sysv run levels.
That does sound really handy. When I was a sysadmin in academia, I'd always try to schedule shutdowns for times when people would be asleep. But of course no matter what time you pick, there's always at least one grad student doing work then. :-)
A few modifications were necessary, on my end. First, I have to add the script:
sudo chkconfig --add runmycommandatshutdown
Second, the argument "on" needed to be at the end of the script:
sudo chkconfig runmycommandatshutdown on
Cheers!
I tried a script on my Fedora 24 box with systemd, but it failed to run. have two possible causes:
1. the article doesn't mention making the script executable -- is it necessary?
2. my script does a 'dnf upgrade -y && dnf clean all' (system upgrade, clean cache) that is only allowed by su, I don't use sudo -- does the systemd routine automatically run root scripts when shutting down as a normal user?
TIA
Thanks for reading. I'm pretty sure the first suggestion is the problem. The script probably does need to be executable. I apologize for leaving that out.