Linux: how to run commands by keypress on the local console

This is probably not the only way to do this, and just something I had to dig up to be able to control the piStorm from the console keyboard without being logged in.

After trying to find some built-in way of doing it, I ended up using ‘lirc’ (‘inputlircd’) to fetch the keystrokes and execute appropriate commands in the background. The guide is not intended to be complete, and it’s not even re-tested because of the trial-and-error attempt on getting this working the first time, and not taking any notes.

The most useful resource for the success was:
How to run script on keypress? (superuser.com)

Required steps to getting started with lirc

Become root

sudo su -

Install required packages:

apt -y install lirc inputlirc input-utils socat

Configuration
Find the input device you wish to capture keypresses from:

lsinput

The not really necessary step
Examine the inputlirc start/stop script “/etc/init.d/inputlirc” to see where it looks for configuration:

...
DAEMON="/usr/sbin/inputlircd"
NAME="inputlirc"
DESC="inputlirc"

test -x $DAEMON || exit 0

[ -r /etc/default/$NAME ] && . /etc/default/$NAME
...

The marked lines in the partial content of “/etc/init.d/inputlirc” reveals that a file “/etc/default/inputlirc” is sourced.

Change startup parameters for inputlircd
“/etc/default/inputlirc” contains parameters for running inputlircd, including the input device to capture events from and the parameters to the service looking for keystrokes.

Read the inputlircd manpage (man 8 inputlircd) to find out which parameters you need/want to use. The below is what I had to put in the file:

# Options to be passed to inputlirc.
EVENTS="/dev/input/event0"
OPTIONS=-m 0 -c

-m 0 = -m sets the lowest keycode to pass to the daemon
I also use -c to allow to capture the modifier keys (CTRL, SHIFT, ALT) so they will be part of a keystroke instead of generating their own events. This will make it possible to use combinations like SHIFT + F1 for command execution.

After editing and saving the file, enable and (re)start the inputlirc service:

systemctl enable inputlirc
systemctl restart inputlirc

Then check that it’s running:

systemctl status inputlirc

Snooping for keypress events
Unless you know all the keycodes you are going to use for running commands, now is a good time to check what lircd receives on specific keypresses. Run the command to snoop for keypresses in the shell, and press keys on the keyboard connected to the computer (this could be connected through USB, PS/2, Bluetooth, IR, whatever)

socat UNIX-CONNECT:/var/run/lirc/lircd STDOUT

Sample output (F12 and modifier keys)

root@raspberrypi:~# socat UNIX-CONNECT:/var/run/lirc/lircd STDOUT
58 0 SHIFT_KEY_F12 /dev/input/event0
58 0 CTRL_SHIFT_KEY_F12 /dev/input/event0

The irexec service
To make the irexec service restart when inputlirc is restarted (due to a key configuration change), the service startup file has to be slightly modified:

/lib/systemd/system/irexec.service:

[Unit]
Documentation=man:irexec(1)
Documentation=http://lirc.org/html/configure.html
Documentation=http://lirc.org/html/configure.html#lircrc_format
Description=Handle events from IR remotes decoded by lircd(8)
After=inputlirc.service
Requires=inputlirc.service
...

Add the lines marked above, then rebuild the systemd service configuration file and enable and start the irexec service:

systemctl daemon-reload
systemctl enable irexec
systemctl start irexec

Check that the irexec.service is running:

systemctl status irexec

Configuring what to run on keypresses
The file “/etc/lirc/irexec.lircrc” contains the configuration for what commands to run when selected key(combinations) are used. Wipe out all the defaults in there and add something useful. Below is the updated, more generic configuration I use on my PiOS for the piStorm now, just mapping some keys to a script with a similar name:

begin
    prog   = irexec
    button = SHIFT_KEY_F1
    config = /home/pi/irexec/shift_f1.sh
end

begin
    prog   = irexec
    button = SHIFT_KEY_F2
    config = /home/pi/irexec/shift_f2.sh
end

begin
    prog   = irexec
    button = SHIFT_KEY_F3
    config = /home/pi/irexec/shift_f3.sh
end

begin
    prog   = irexec
    button = SHIFT_KEY_F4
    config = /home/pi/irexec/shift_f4.sh
end

begin
    prog   = irexec
    button = SHIFT_KEY_F5
    config = /home/pi/irexec/shift_f5.sh
end

begin
    prog   = irexec
    button = SHIFT_KEY_F6
    config = /home/pi/irexec/shift_f6.sh
end

begin
    prog   = irexec
    button = SHIFT_KEY_F7
    config = /home/pi/irexec/shift_f7.sh
end

begin
    prog   = irexec
    button = SHIFT_KEY_F8
    config = /home/pi/irexec/shift_f8.sh
end

begin
    prog   = irexec
    button = SHIFT_KEY_F9
    config = /home/pi/irexec/shift_f9.sh
end

begin
    prog   = irexec
    button = SHIFT_KEY_F10
    config = /home/pi/irexec/shift_f10.sh
end

begin
    prog   = irexec
    button = SHIFT_KEY_F11
    config = /home/pi/irexec/shift_f11.sh
end

begin
    prog   = irexec
    button = SHIFT_KEY_F12
    config = /home/pi/irexec/shift_f12.sh
end

begin
    prog   = irexec
    button = CTRL_SHIFT_KEY_F12
    config = /home/pi/irexec/ctrl_shift_f12.sh
end

Whenever you have made a change to /etc/lirc/irexec.lircrc, you need to restart inputlirc (which automatically restarts liexec):

systemctl restart inputlirc

Action scripts in /home/pi/irexec
These scripts can be updated without having to restart inputlirc. Be sure to set the execute flag on them (chmod 755 /home/pi/irexec/*.sh)
For the piOS installation for the piStorm, the content of my configuration-switching scripts are as follows:

/home/pi/irexec/shift_f1.sh (the F-keys 1-10 with the SHIFT key held down):

#!/bin/sh
cp /home/pi/cfg/a1200_4068_os31.cfg /home/pi/default.cfg
sudo systemctl restart pistorm

In a similar way, I have set up the other shift-f-key combinations as shown in the video.

I have used SHIFT+F12 for a safe reboot, and CTRL+SHIFT+F12 for a shutdown of the pi. If running piStorm in RTG mode there can be a delay of about 1 minute before something happens.

/home/pi/irexec/shift_f12.sh:

#!/bin/sh
sudo systemctl stop pistorm
sudo reboot

/home/pi/irexec/ctrl_shift_f12.sh:

#!/bin/sh
sudo systemctl stop pistorm
sudo halt -p

You can check the status of the piStorm service to see that it received the shutdown command:

root@raspberrypi:~# systemctl status pistorm
● pistorm.service - Start piStorm 68k emulator
   Loaded: loaded (/lib/systemd/system/pistorm.service; disabled; vendor preset: enabled)
   Active: deactivating (final-sigterm) since Sat 2021-04-24 23:48:43 BST; 1min 6s ago
  Process: 1023 ExecStart=/home/pi/start-emulator.sh (code=killed, signal=TERM)
 Main PID: 1023 (code=killed, signal=TERM)
    Tasks: 10 (limit: 873)
   CGroup: /system.slice/pistorm.service
           ├─1024 sudo ./emulator --config /home/pi/default.cfg
           └─1025 ./emulator --config /home/pi/default.cfg

Apr 24 13:23:53 raspberrypi start-emulator.sh[1023]: [MUSASHI] Mapped read range 4: 40000000-48000000
Apr 24 13:23:53 raspberrypi start-emulator.sh[1023]: [MUSASHI] Mapped write range 3: 40000000-4800000
Apr 24 13:23:53 raspberrypi start-emulator.sh[1023]: Platform custom range: 00E90000-80010000
Apr 24 13:23:53 raspberrypi start-emulator.sh[1023]: Platform mapped range: 00200000-48000000
Apr 24 13:23:53 raspberrypi start-emulator.sh[1023]: RTG display disabled.
Apr 24 13:23:53 raspberrypi start-emulator.sh[1023]: Pitch: 800 (800 bytes)
Apr 24 13:23:53 raspberrypi start-emulator.sh[1023]: RTG thread running
Apr 24 13:23:53 raspberrypi start-emulator.sh[1023]: error: XDG_RUNTIME_DIR not set in the environmen
Apr 24 23:48:43 raspberrypi systemd[1]: Stopping Start piStorm 68k emulator...
Apr 24 23:48:43 raspberrypi systemd[1]: pistorm.service: Main process exited, code=killed, status=15/
root@raspberrypi:~# 

Revised start-emulator.sh script
Because I want to run the wip-crap version of the emulator at some points, I have added a check for the mentioning of “wip-crap” in the configuration file that is going to be used, then depending on its existance or not, launching the emulator from the correct directory:

#!/bin/sh
if grep -q wip-crap "/home/pi/default.cfg"; then
  echo "wip-crap"
  cd /home/pi/pistorm-bnu/
else
  echo "main"
  cd /home/pi/pistorm/
fi
sudo ./emulator --config /home/pi/default.cfg
exit 0

To enable the wip-crap version, just add a comment in the beginning of the configuration such as:

# using wip-crap functions

3 thoughts to “Linux: how to run commands by keypress on the local console”

  1. This is a very cool solution and definitely adds a ton of utility to a PiStorm equipped Amiga! One drawback that I noticed is that the lirc package has a massive dependency tree, and ends up pulling in a bunch of gtk 3.0 libraries which is not ideal for a light-weight OS install. It might be an interesting project to explore alternatives there!

Leave a Reply

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