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.
How would you shutdown your headless rpi without network connectivity?
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?
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 and
interprets the event data received and executes scripts configured in its
Just give me the steps already!
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 trigger
Connect your mouse (or any other input device) to rpi. Find out the event name of your click/tap by running
thd --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
# Announce to all terminals
wall 'A mouse forced me to shut down'
# The actual shutdown command. sudo is used because shutdown
# needs root previlages
sudo /sbin/shutdown now
Make the script executable
sudo chmod +x /etc/trigger.sh
Create the triggerhappy config file
Create 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
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”.
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
sudo without requiring password.
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 later
nobody 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
And we’re done.
Attach the mouse to your rpi, right click and watch the rpi turn off.