Raspbian: Wrap Your App

How to autostart your app if it needs keyboard access, protect it against malicious Ctrl-wielding users, and shut the system down properly without locking yourself out forever!

Disclaimer: I’m no Linux expert by any stretch of the imagination; use at your own risk. And if you see any mistake or know of a better way to do these things, please let me know 🙂 

…So I built this little system, where you type a secret password on an off-the-shelf keyboard and it makes an LED thingy light up. But that’s not the point. What’s important is that to in order make it closer to a real-life system, I had to learn some things about Raspbian (the go-to operating system for Raspberry Pis). Those are issues that bug many people, but the answers to which are scattered all around the web, hidden or out of date. Therefore I decided to put it all in one place.

  1. When installing the OS

For my system I chose Raspbian Stretch Lite (find it here); This is the same as the “usual” Raspbian, except that it doesn’t have the graphics and desktop, only the CLI (textual Command Line Interface). This version takes less space and – I am led to believe – loads a bit faster. Not recommended for total noobs though, as they’ll have to learn a bit about Linux first, to get anything to work.

When the OS runs for the first time, it’s good practice to change the default password (“raspberry”) for the default user (“pi”). We do this by typing

sudo raspi-config

and selecting the proper menu item. We’ll also need to go to Boot Options->Desktop/CLI and select Console Autologin, so that our programs will be able to run without the Pi requesting usernames and passwords on every power-up. If you’re not British, do yourself a favour… favor and go to Localization Options->Change Keyboard Layout to select the English (US) type, or whatever’s appropriate for you, instead of the default English (UK). Leave the other keyboard parameters as the defaults.

2. Autostart a program with stdin (i.e. keyboard) access

The common wisdom regarding automatic running of applications in Raspbian is to put the run command inside the file /etc/rc.local . This works in most cases, but – as it turns out – not if you want your program to be able to get user input from the keyboard. rc.local runs your code in a different context, as it were, outside the usual login terminal, and can’t see the keyboard. To gain access to it you’ll have to put the command in the file .bashrc that’s hiding in your (user) home directory.  This will cause your program to run within the context of the logged-in session and accept keyboard input.

Just for fun, a literal screenshot of my application's code
Just for fun, a literal screenshot of my application’s code

3. Protecting against Ctrl+C and Ctrl+Alt+Del

If our system runs in a public information kiosk or anything like that, we definitely don’t want users to press Ctrl+Alt+Del, which will restart the system by default, or worse – Ctrl+C which will terminate the running program and return to the CLI. We could just glue the Ctrl keys physically, but there are also software solutions. The linux “trap” command lets us, well, trap signals such as Ctrl+C (signal #2, also known as SIGINT), and state what will handle them, if anything. Let’s say we have a Python 3 program called myProg.py, and we want to make sure the user can’t use Ctrl+C while it’s running; so in .bashrc, or other script file, we’ll write three commands (and two comments):

# Disable the normal processing of SIGINT
trap '' 2
python3 myProg.py
# Re-enable processing of SIGINT
trap 2

With Ctrl+Alt+Del it’s different; the most straightforward way is to disable it once, globally, assumming you won’t really need it in the foreseeable future. Following the advice here, erase the file

/lib/systemd/system/ctrl-alt-del.target

to prevent it from executing the default behavior, and then re-create it as a symbolic link to /dev/null, or in other words, to nothing:

sudo ln -s /dev/null /lib/systemd/system/ctrl-alt-del.target

If you’re not in a hurry, just restart the system whenever’s comfortable and then the change will take effect.

4. Killing it softly

At some point you may want to shut down your system, and do it gracefully instead of just pulling the plug (an action that may harm some OS files).  The command for this is

shutdown -h now

and you can put it at the end of .bashrc or other such script file. However, you’ll have to consider carefully the trigger that will cause your application to stop running (again, you don’t want a malicious user to be able to do it). Another important issue is that if you just write this command, you’re essentially blocking yourself from your own system. After all, your application starts automatically, and when it’s done, the Raspberry Pi shuts down automatically. There’s no in-between where you can access the files and make changes!

I can’t think of a generic solution that will fit each and every use case; in my own system,  I added a short period after the termination of the program, in which the user can type something on the keyboard. If he or she does, then the system will return to the CLI. otherwise, the shutdown command will execute. All this is done in script, and can be put at the end of .bashrc. Here’s an example for a 10-second wait for any kind of keyboard input. Note that in order to return to CLI, the user has to type something AND press ENTER before the time is up. Note also the peculiar structure of the “if” command!

echo "Type something in 10 seconds to return to CLI"
read -t 10 userResponse
if [userResponse == ""]
then
  shutdown -h now
fi

2 thoughts on “Raspbian: Wrap Your App”

  1. To shut down the system, use “shutdown -h” without the “now.” It will shut down after 60 seconds and can be aborted during that time by running “shutdown -c” and using “shutdown -h +[num]” (replacing [num] with an actual number” will shut it down in [num] minutes (so “shutdown -h” and “shutdown -h +1” are equivalent.)

    And if running the device in kiosk mode, consider setting the file-system in read-only mode (see advanced settings in raspi-config.) This is much the same as running a live-CD. If it’s rebooted, it goes right back to the way it started and any changes in the files or settings are dropped.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.