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
EmoticonEmoticon