The suggested solution is to run the service unit as a normal service - have a look at the [Install]
section. So everything has to be thought reverse, dependencies too. Because the shutdown order is the reverse startup order. That's why the script has to be placed in ExecStop=
.
The following solution is working for me:
[Unit]
Description=...
[Service]
Type=oneshot
RemainAfterExit=true
ExecStop=<your script/program>
[Install]
WantedBy=multi-user.target
RemainAfterExit=true
is needed when you don't have an ExecStart
action.
After creating the file, make sure to systemctl daemon-reload
and systemctl enable yourservice --now
.
I just got it from systemd IRC, credits are going to mezcalero.
If I understand you correctly, you want to suspend your VB machines before your bash session on tty3 terminates, or before your Xserver terminates.
I believe systemd is unaware of your running Xsession, because you start it from your .bashrc, so it will be difficult to tell systemd to suspend your VBs before it terminates your shell or your Xsession. You will have to find a place in the shutdown sequence which is "early enough", which might be difficult to find and semantically questionable, because it would mix "user stuff" with "system stuff"
The solutions may somewhat depend on how systemd terminates your processes, but the following should at least point in a good direction:
Before the shell terminates
suspendVB() {
echo "suspending VBs"
# put real code here
exit
}
trap suspendVB EXIT
If you make this the rcfile of your bash (or add it to .bashrc), then the code in suspendVB()
will be executed before the shell terminates. You can test this by running
bash --rcfile xxx
where the file xxx
contains the code from above. This starts another shell inside your current shell, just for testing. When you then run a simple exit, you will see:
martin@beaureve:~$ exit
exit
suspending VBs
/home/martin >
and you are back in your original (login) shell.
You may have to find out how systemd actually terminates your login shells, and you may have to replace EXIT
by some other signal(s). Lookup the trap
command to find out more.
Note that When systemd kills your processes with "-9" (SIGKILL) then you will not be able to trap the termination, i.e. you're out of luck.
Before the Xsession terminates
Alternatively you may try a similar thing with your Xsession. This is essential in cases where systemd terminates your Xsession before it terminates your shells. You may want to insert a trap in one of the X startup files (e.g. .xinitrc) - lookup the man pages for startx
and xinit
to find out more.
If your startx
file looks something like mine, then the xserver is started in foreground and you can alternatively simply place your suspend commands after the line where X is actually started (and not use traps at all):
xinit "$client" $clientargs -- "$server" $display $serverargs
retval=$?
echo " --- suspending VBs ---"
I put in the line saying "suspending VBs" and when I run startx -- vt8
I get a fullblows (kde) session on vt8 and only when I logout, the line "suspending VBs" appears on the screen.
Best Answer
I've finally found how to do that.
It's a bit hackish thought, but it works.
I've used some part of this thread : https://stackoverflow.com/questions/25166085/how-can-a-systemd-controlled-service-distinguish-between-shutdown-and-reboot
and this thread : How to run a script with systemd right before shutdown?
I've created this service
/etc/systemd/system/shutdown_screen.service
Which will be executed at shudown/reboot/halt/whatever. (don't forget to enable it)
And in my script
/usr/local/bin/shutdown_screen
I put the following :Which will send a shutdown message to my arduino, whom will shutdown my screen.