A Raspberry Pi 3
Raspberry Pi (aka rpi) is a nice little thing. It is cheap, runs debian from an SD card. Doing anything on it is fast and easy, as long as you don’t use it as a headless device.
Headless devices are those devices which don’t have peripherals like monitor, mouse or keyboard attached. They essentially are at their bare minimum: Power and Networking. (These can run lightweight distros without GUI). The only way of accessing these machines is through a serial-to-usb adapter or ssh. Particularly, access through ssh presents its own problems.
There is an entire thread on reddit dedicated to shutting down headless pi’s. Most of the answers revolve around attaching a button to GPIO or buying an addon board. There are quite a lot of solutions involving buying stuff.
Am I going to buy stuff? No way!
Once upon a time, Stefan Tomanek wrote something named triggerhappy. In his words,
Triggerhappy is a hotkey daemon developed with small and embedded systems in mind, e.g. linux based routers. It attaches to the input device files andinterprets the event data received and executes scripts configured in itsconfiguration.
To shutdown the pi, we are going to plug in a mouse into the pi’s USB and right click. We will configure triggerhappy daemon to listen for this event and call the shutdown command.
Find the event code of triggerConnect your mouse (or any other input device) to rpi. Find out the event name of your click/tap by runningthd --dump /dev/input*
. This should list the events related to your click. In my case, it was BTN_RIGHT 1
for mouse right button down and BTN_RIGHT 0
for button up.
**Create the shutdown script**Make a file /etc/trigger.sh
with
#!/bin/bash
# Announce to all terminalswall 'A mouse forced me to shut down'
# The actual shutdown command. sudo is used because shutdown# needs root previlagessudo /sbin/shutdown now
Make the script executable
sudo chmod +x /etc/trigger.sh
Create the triggerhappy config fileCreate a file /etc/triggerhappy/triggers.d/mouse-poweroff.conf
with the following contents. (Replace BTN_RIGHT
with your trigger event code from the first step)
BTN_RIGHT 1 /etc/trigger.sh
Restart triggerhappy
sudo systemctl restart triggerhappy.service
Well, isn’t it supposed to work already? _Nope._triggerhappy, executes our script as a user called nobody
. According to wikipedia,
In many Unix variants, “nobody” is the conventional name of a user account which owns no files, is in no privileged groups, and has no abilities except those which every other user has. Some systems also define an equivalent group “nogroup”.
The shutdown
command needs root previlages to actually power off the pi. nobody
actually cannot execute any command with superuser privilages. We are going to bypass that now. We need to allow user nobody
to execute shutdown
with sudo
without requiring password.
Now, sudo visudo
will open an editor to edit the sudoers
file. Append the following at the end, save and exit.
# We add echo command for testing. Remove laternobody ALL =NOPASSWD: /bin/echo*,/sbin/shutdown*
Warning: This is not a clean or secure way, since we are granting permission for nobody
to shutdown your pi.
To see if it works, sudo su -s /bin/bash nobody
from your current user and check if you can sudo echo 'hello world'
as nobody
.
Attach the mouse to your rpi, right click and watch the rpi turn off.