Extending the remote control capabilities of LIRC

If you have installed the LIRC package on your computer so that it can receive signals from an infrared remote control (as we showed how to do in Ubuntu 18.04 in our previous article, Make LIRC work in Ubuntu 18.04, so that you can use your infrared remote in Kodi), you may have thought that you could only utilize it inside programs that have remote control support built-in, such as Kodi.  But did you know that you can also use your remote to execute any command that can be executed from a Linux command prompt, or even run a shell script to execute multiple commands?

In order to do that you need to do at least two things.  First, you need to run the irexec program (which is installed as part of the LIRC package), and second, you need to create a .lircrc file in your user directory.  In addition, you may wish to create shell scripts to do whatever you want.

An example may make things easier to understand.  Let’s take the case of starting or restarting Kodi from the desktop.  Let’s say you have just started up your system and it is sitting at the desktop waiting for you to start a program, and you want to start Kodi.  Sure, you could use your mouse to select Kodi and start it, but it’s more convenient to just be able to push a button on the remote to do it.  Or maybe you have been using Kodi and it has simply frozen up on you – wouldn’t it be nice to be able to push a button, kill the frozen instance of Kodi, and then restart Kodi?

Windows Media Center Edition compatible remote controlMost Windows Media Center Edition compatible remotes have four colored buttons, colored red, green, yellow, and blue, that don’t do anything inside Kodi by default. But, LIRC still recognizes them, and they are perfect for use in such an application.

The first thing you would need is a script to start Kodi.  Here’s a bash script that we use with Kodi 17.  Note that in Kodi 18 (at least in beta versions) some changes will need to be made, and these are noted in comment lines. Also note the comments about changing the value of yourusername in the “export USER=” and (optional) “sudo nice” lines:

# For Kodi V18 change AE_SINK=ALSA to KODI_AE_SINK=ALSA and
# all instances of kodi.bin to kodi-x11

# In the line below replace yourusername with your actual
# user name in Ubuntu (this will probably be the same as
# the name of your user directory)
export USER=yourusername

# Now try to kill existing Kodi if it is running
if ps -ef|grep -v grep|grep -i kodi.bin
ps aux|grep -i $USER|grep -v grep|grep -i kodi.bin|awk '{print $2}'|xargs kill
sleep 3

# If it's still running, force kill it using kill -9
if ps -ef|grep -v grep|grep -i kodi.bin
ps aux|grep -i $USER|grep -v grep|grep -i kodi.bin|awk '{print $2}'|xargs kill -9
sleep 3

# If it's STILL running it won't die, so exit
if ps -ef|grep -v grep|grep -i kodi.bin

# Delete old Kodi crashlogs (optional)
/bin/rm -f ~/kodi_crashlog-????????_??????.log

# Start Kodi using ALSA sound system
AE_SINK=ALSA kodi --standalone &

# Comment out the above line and uncomment the one below
# to give Kodi highest CPU priority, but note that
# 'sudo nice' must not require a password!
# If you uncomment the line below replace yourusername
# with your actual user name in Ubuntu (this will
# probably be the same as the name of your user directory)

# sudo nice -n -20 su yourusername -c 'KODI_AE_SINK=ALSA kodi --standalone &'

We saved this script as startkodi.sh and made it executable:

chmod +x startkodi.sh

Please note that we start Kodi with some specific options that you may or may not wish to use. To break them down:

AE_SINK=ALSA (this will change to KODI_AE_SINK=ALSA in Kodi 18): This usually forces Kodi to use the ALSA sound system rather than PulseAudio, which can give better performance if you are using passthrough audio in a multichannel system (5.1 or 7.1 audio). We say usually because on at least one system it was necessary to take more aggressive steps to kill PulseAudio before this would work (see the section headed “Disabling daemon autospawn” on this wiki page if you have this problem). You will know if it is working because you’ll need to reset your audio output under System Settings | System | Audio to use the ALSA output (and the PulseAudio options will disappear). If you are not using passthrough audio (using the “Allow passthrough” setting, and selecting a Passthrough audio device), then there is probably no reason to use this.

kodi - -standalone: The recommended way to run Kodi from a shell script. (Please note there is a hidden character between the two – (hyphen) characters in this line, to force WordPress to display it correctly, so if you copy and paste this it won’t work if you don’t remove that hidden character.  Unfortunately, this is the case anyplace you see two adjacent hyphens in this article, except when they are within a code block.)

&: The ampersand at the end allows the script to exit immediately, without shutting down Kodi. It effectively makes Kodi a background task.

If you use the optional line to start Kodi with the highest CPU priority, sudo nice -n -20 does that but here is the problem – in Ubuntu you can’t use a negative “nice” value without using sudo, which runs “nice” as the root user. You probably want Kodi to be “not nice” and grab as much CPU time as it can get to avoid dropped frames and other video problems as much as possible. However, you don’t want Kodi to run as root, because then any malicious Kodi addon or even possibly a maliciously crafted video stream could do bad things to your system. So you have to have sudo (run as root user) apply only to the “nice” command, and not to any of the commands applicable to Kodi. The su yourusername -c part of the line takes care of that, by running the rest of the line as your normal user, not as root. It’s a bit convoluted, but it works, however there’s a catch – in order for it to work, you’ll need to edit the /etc/sudoers file so that “sudo nice…” won’t prompt for the user’s password! First verify the correct path to the “nice” command:

which nice

Most like it will return /usr/bin/nice (if not, change it to the correct path in the instructions below). Then do:

sudo nano /etc/sudoers

Move the cursor to the end of the file and on a new line add this (using the correct path to the “nice” command):

yourusername ALL = NOPASSWD: /usr/bin/nice

Replace yourusername with your your actual user name in Ubuntu. Use Ctrl-X to exit nano, and save the file. This allows running “sudo nice” without needing to enter a password, so it will work when you invoke it using your remote control.

Do NOT try to use a line such as “AE_SINK=ALSA kodi nice -20 –standalone &” because Linux punishes you for trying to do that as a mere user (not as root) and actually runs Kodi at the lowest possible CPU priority (because you didn’t use sudo)!!! We consider that a very serious bug; if nice can’t set the requested value it should simply ignore the command or even throw a fatal error, but it should not make the program run “nicer” by giving away as many CPU cycles to other programs as possible!

So that is the script we use to start Kodi, and of course we could run that from a terminal window (which you may want to do in order to check for errors), but that would not be very convenient. So, we use the .lircrc file (in the user’s home directory) to start the script when a button is pressed. We’ll use the green button in this example. Start by editing the file .lircrc (if it doesn’t already exist, this should create it):

nano ~/.lircrc

And just paste in these lines:

 prog = irexec
 button = KEY_GREEN
 config = ~/startkodi.sh &
 repeat = 0

Then you can use Ctrl-X to exit nano (be sure to save the file).

The only other thing you need to do is make sure that the irexec program runs at startup. To do that, from the Ubuntu desktop bring up Startup Applications, and when it comes up click the Add button and enter these values:

Name: irexec
Command: irexec -d
Comment: Whatever you want, we used “Infrared Remote Control”

Add irexec to startup programs
Click the Add button to save it.


Once the system has rebooted, you should be able to press the green button and it should run the startkodi.sh script and start Kodi. If it doesn’t, it’s probably because your remote is using different labels for the buttons, and we’ll cover how to determine that in a moment.  In case you are wondering, the -d option used with irexec is what makes it run as a background task.

Now maybe you’d like to be able to push the red button to stop Kodi in case it is hung, but without restarting it.  All you need to do is copy the startkodi.sh script to another script (call it stopkodi.sh), then edit that script to remove the line that starts Kodi, and then edit the .lircrc configuration to add another section:

 prog = irexec
 button = KEY_RED
 config = ~/stopkodi.sh &
 repeat = 0

We can also run system commands directly from the .lircrc file. Let’s say we wanted to use the blue button to reboot the system, in case things really get messed up. We could add this to .lircrc:

 prog = irexec
 button = KEY_BLUE
 config = sudo reboot
 repeat = 0

You would think this would work, but it won’t because when it tries to run sudo it will prompt for your password, and the script can’t deal with that. In order to avoid that, you’ll need to edit the /etc/sudoers file:

sudo nano /etc/sudoers

Move the cursor to the end of the file and on a new line add this:

yourusername ALL = NOPASSWD: /sbin/reboot

Replace yourusername with your your actual user name in Ubuntu. Use Ctrl-X to exit nano, and save the file. This allows running “sudo reboot” without needing to enter a password.

Remember that you will need to REBOOT THE SYSTEM before any changes take effect!

Now, if you are lucky these .lircrc configurations will work as shown. But if you have a different type of remote, you may need to use different buttons, or maybe the buttons aren’t returning the values that .lircrc is expecting to see. To determine that, from a Linux command prompt run this:


Then while watching the terminal window or ssh session, press the buttons you are trying to use on the remote. As an example, here is what we see when we press the green button:

$ irw
000000037ff07ba3 00 KEY_GREEN mceusb
000000037ff07ba3 01 KEY_GREEN mceusb

Press Ctrl-C to exit irw. The thing you are looking for here is the button name, in this case it is KEY_GREEN as shown in the .lircrc section that starts Kodi above, but if your remote returns something other than that, that’s what you’ll need to use in the .lircrc file.  By the way, it is not unusual for a remote to send a button press two or three times in a row, just in case the infrared receiver misses it the first time.  This is not a cause for concern.

When you use irw as shown above, remember that lirc is still running, so don’t press any buttons that would take any action you don’t want to have happen, such as rebooting the system or launching Kodi or something else.


When you use irw, there’s a slight chance you might notice that your remote has one or more buttons that don’t generate any output at all, and maybe you’d like to make them recognized. Or, maybe you’d like to use a second remote (perhaps one that came with a device that you no longer use) to control some additional functions. These things are possible (usually) but the procedure is slightly complicated. One thing to keep in mind is that infrared receivers are only responsive to a certain part of the spectrum of infrared light, and some remotes may generate light pulses outside that range, in which case a particular remote may not work with a particular infrared receiver. But it’s worth a try.

Here’s the basic procedure for getting LIRC to recognize additional buttons:

Open the file /etc/lirc/lircd.conf in a text editor, or just do cat /etc/lirc/lircd.conf from a Linux command prompt, and note the contents – more than likely it will contain an “include” statement such as

include "/usr/share/lirc/remotes/mceusb/lircd.conf.mceusb"

Open THAT file in a text editor and note how it is constructed. You will probably see definitions for one or more remotes, in sections between “begin remote” and “end remote” tags. In each such section you will see a list of codes, in sections between “begin codes” and “end codes”, and in such sections you will see two columns. The first is a list of names that have already been used for existing remote buttons, and that you therefore should not use when adding new buttons.

However, you cannot just go using any button names you like for your new buttons. You can only use the button names that are shown when you run this command from a Linux command prompt:

irrecord - -list-namespace

(Please note there is a hidden character between the two – (hyphen) characters in the above line, to force WordPress to display the line correctly, so if you copy and paste the above it won’t work if you don’t remove that hidden character.)

So to try to make this clear, when naming a new button you can only use names that appear in the list you get when you run irrecord - -list-namespace but you should NOT use names that appear in the /etc/lirc/lircd.conf file, or in any file that is mentioned in an include statement within that file, because you run the risk of specifying the same button name for two different buttons.

You may have to read that a couple of times for it to sink in, but it’s important. You will probably want to find a way to keep both lists visible during the next steps. You could open them in two different Text Editor windows, or two different terminal windows, or two different ssh sessions from another computer – it really doesn’t matter as long as you can refer to both lists, and know which is which.

Now you are ready to try to map new buttons. During this process, lircd cannot be running, so do this:

sudo killall lircd

Now at this point we will advise you to read the rest of this article before you do anything, but we know you probably won’t so we will just note that after you do anything mentioned below, you are going to need to REBOOT THE SYSTEM before any changes you have made will take effect, and to restart lircd.  This seems to be an easy thing to forget and you can literally waste hours trying to figure out why things aren’t working just because you failed to REBOOT THE SYSTEM.  Don’t ask us how we know…

Next, run this command:

sudo irrecord -d /dev/lirc0 ~/newremote.txt

The character at the end of lirc0 is a zero, not a letter O. You can use any filename you want rather than “newremote.txt”, just make sure it’s a filename you aren’t already using. When using irrecord, don’t try to add buttons from more than one remote in a single run, and if you make a mistake just Ctrl-C out, delete the “newremote.txt” file, and start over. Also, note the above line assumes that /dev/lirc0 is the correct path for LIRC’s connection to your infrared receiver, which is almost always the case, but one time we did see a situation where /dev/lirc1 was correct.  If you use the wrong path you may get a weird permissions error or some other error when you try to run irrecord.

The irrecord program will walk you through the entire procedure for adding new buttons — just follow the instructions it gives precisely. It will first have you perform some tasks so it can determine basic timing information about your remote.  If irrecord can’t seem to detect your remote, it may be that the remote isn’t compatible with your infrared receiver, or it may be that the batteries are dead in the remote! Don’t give up on a remote without at least trying new batteries.

After the preliminary tasks are completed, irrecord will ask you to enter the name of a button. This is when you will refer to the two lists — remember, you want to use a name that DOES appear in the irrecord - -list-namespace list, but that does NOT currently appear in /etc/lirc/lircd.conf or in any file referenced by an include statement therein (such as /usr/share/lirc/remotes/mceusb/lircd.conf.mceusb in our example above).  Just to be clear, there is no requirement that the names you use in this procedure be in any way related to the names of the buttons on the remote, since you will be defining what the button press actually does in the .lircrc file.  It may be convenient to use a related name (if it’s not already used in another remote’s codes list) to help you remember which button is associated with which name, but if you can’t find an unused name that comes close to the name of the button on your remote,  it’s perfectly okay to pick any unused name from the irrecord - -list-namespace list and use that, though in that case you may want to make notes about which names are associated with which buttons.

After you enter the name, it will ask you to hold down the button on the remote. After a few moments it should ask you to enter the name for your next button – that is your confirmation that the button was accepted by your infrared receiver. You can keep on adding new buttons from the same remote, or exit by pressing only the Enter key when asked for the name of the next button.

If you get the error “Something went wrong. Please try again.” then you can use Control-C to exit the program, delete the file it created (~/newremote.txt, or whatever name you used, and start over but this time add the -f option:

sudo irrecord -f -d /dev/lirc0 ~/newremote.txt

Then try repeating the above procedure.  This will force raw mode, which is apparently the only way that the buttons from some remotes can be recorded.  You can also get weird errors if you happen to have more than one lirc device, such as lirc0 and lirc1, and lirc1 is the one associated with your IR receiver rather than lirc0.  You can do

ls /dev/lirc*

to see if you have more than one lirc device.  If you do, you might need to substitute /dev/lirc1 in place of /dev/lirc0.

Once you have exited irrecord, you must open the file it created (~/newremote.txt, or whatever name you used) in a text editor, and change the value on the name line (right below the line that reads “begin remote”) to something with NO SPACES – underscore characters are okay, though.  So, something like

 name new_remote

would be fine.  The name must not duplicate the name in any of your existing remote definitions.  Also, we always remove all the commented-out lines produced by irrecord (lines that begin with a # character), since they are not needed.  Newer versions of irrecord may ask you for the name you want to use for the remote, and in that case you may not need to change anything.

After you have made those changes, copy the section starting with “begin remote” and ending with “end remote” to the clipboard, and then open the file containing your other remote definitions and carefully paste your new remote definitions to the end of that file (leave at least one blank line after the existing contents of the file before pasting).  By “the file containing your other remote definitions” we mean either /etc/lirc/lircd.conf or the file that is mentioned in an include statement within /etc/lirc/lircd.conf, such as /usr/share/lirc/remotes/mceusb/lircd.conf.mceusb in our above example (we used the latter).  The basic idea is you want to put your new remote definitions and codes at the end of the same file that contains all the other remote definitions and codes. BE CAREFUL when doing this because if you somehow screw up this file, your remote may not work at all!  It probably isn’t the worst idea to make a backup of the file prior to making any changes.

If you don’t want to mess with your existing remote definitions file, you could probably add a new include line within /etc/lirc/lircd.conf and point that to a new file that you have created that contains your new remote definitions.  That is supposed to work, according to the LIRC documentation, but we haven’t actually tested doing it that way (please note that the LIRC documentation link takes you to the documentation for the latest version of LIRC, and therefore some parts may not be applicable if you are using an older LIRC version).

Note that if you were trying to add buttons from your main remote that LIRC has not previously recognized for some reason, you will probably want to add just those new codes directly to the existing codes list for that remote, rather than copying the entire new block of remote definitions.

You will probably want to save a backup of your new remote definitions someplace, so you don’t have to go through this process again the next time you upgrade the system!  This comment comes from experience — during our most recent Ubuntu upgrade, we backed up the entire home directory and some specific configurations from the /etc directory, but we totally forgot about the remote definitions that we had put into the /usr/share/lirc/remotes/mceusb/lircd.conf.mceusb file, so we had to do redo this process.

Once you have added your new remote definitions and codes to the file containing your existing remote definitions and codes and saved it, you should REBOOT THE SYSTEM so that lircd will restart and read in the new codes.  After the system is rebooted, you can once again run irw and now when you press one of the buttons you added, it should show the name that you assigned to the button.  And if that works, you can then use that button name in the .lircrc file to launch shell scripts or system commands, or do just about anything you could do from a Linux command prompt.

Addendum:  Mind the Gap!  No, we haven’t been riding the London underground, but we have discovered that on some systems, but not others for some weird reason, if you add remote definitions that contain a “gap” value in the headers — which almost all added definitions will — it may cause LIRC to stop working altogether if for whatever reason irexec doesn’t like the gap value.  So if you have a gap value that is a bit on the high side (near or above 100000) you may need to reduce the gap value to get things working again.  For example in one case the gap value should have been 108382, but we wound up having to reduce it to 80000 on just one system for it to work, even though the higher value works fine on several other systems, and even though some of the other remote definitions had higher gap values.  The real issue is that if you get bitten by this, your remote won’t work at all until you change the gap value to something that irexec approves of — it will just silently fail to recognize your remote! This may even be a problem when you are copying remote definitions from one system to another — the gap value that works just fine on one system will cause the failure of your remote control to work at all on a different system.


One thought on “Extending the remote control capabilities of LIRC

  1. Just excellent !

    People have forgotten how useful and cheap IR-USB remotes are compared with phone + apps.


    1. How can we use multiple remotes via LIRC to run multiple Kodi instances on “Kodi” TV boxes ( say Amlogic or Rockchip SoCs with USB ports and also a single IR remote included)?

    The idea here is to run a 2nd Kodi instance to be controlled by an additional IR remote connected via USB port, with an IR-USB dongle.

    TV boxes come with both an HDMI and an AV port. So in principle it should be possible to run one Kodi instance display on HDMI and the 2nd Kodi instance display on AV, via separate remotes and some finagling with Event_Server module?

    2. Can an LIRC based remote control be used with miniDLNA server streaming to a DLNA player?

    I am thinking an openwrt router with miniDLNA and usb stick…

    Here the idea is to substitute a cheap IR-USB remote device for a phone+ DLNA app !


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

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