System.Exec Function


Regular Kodi user, hadn’t realised I wasn’t registered in OSMC.

I am trying to run a bash function from System.Exec. Through all sorts of debugging I’ve simplified down to trying the following:

I have editted DialogButtonMenu.xml in confluence skin to change shutdown behaviour from Shutdown() to →

System.Exec(“/home/osmc/”) is executable and owned by osmc contains:

echo Hello World > /home/osmc/test.txt

So all I am expecting is a file called test.txt to appear containing Hello World. This works fine if I call from a terminal.

On Kodi however I get no test.txt, the dialogbuttonmenu clears and I start getting artefacts on the home screen and eventually Kodi restarts. On the first restart I get a mix of odd activity like “Web Server failed” and usually a complete lock up, not responding to remote or keyboard, on a 2nd manual restart (from terminal) I get normal service back.

I have searched the forum for subjects relating to System.Exec and it seems all of those queries lead to people finding a way to achieve what they wanted without it (Usually writing their command in python and doing a Runscript).

Can someone confirm that System.Exec does actually work? And if there are any specific OSMC syntax requirements?

The paste below of the kodi.log when I try pressing the button. The relevant sections starts at 16:12:16 1266.265747 with the dialogbuttonmenu opening. It looks like it trys to open the file as an audio sink?! and then crashes out when it can’t?

I hope this isn’t me just being a NOOB, but kind of also hope it’s not a bug either.

(If this gets resolved what I would actually like is to recognise a CEC status message coming in saying the the TV has gone to standby but instead of Kodi shutting down (like the CEC options allow) use that trigger to run a script which redirects the network interface from a remote server. I want the Pi to remain running when TV off, but to drop its SMB connection.)



Edit: not relevant

If this is just a non-thing then I’d be just as appreciative of someone telling me so :smile:

From what I can remember from other threads System.Exec() does not work properly, but nobody has dug into it to find why. It seems to cause another copy of kodi.bin to be forked and run as normal rather than a fork and exec call that you would expect when forking a shell as a child process.

This causes two copies of Kodi to be running which is what causes the graphical glitches and listening socket to fail as the port is already be in use. As you say, the workaround seems to be to use RunScript() to call a python script instead.

CC @sam_nazarko

Ok. Thanks for letting me know. Just wanted to check it wasn’t me.

I was trying to use bash as I’d never used Python but getting to grips with that in the past few days, so makes it much less of an issue.

subprocess seems a pretty reliable module for pulling direct bash functions.

Once you get the hang of it, python is actually pretty good. A bit of overhead to use it to run shell commands but you may find that what you’re trying to do can sometimes be better done by Python anyway.

I’ve added this bug on our issue tracker so it doesn’t get forgotten and we will try to investigate it when we get a chance. (I first noticed the problem a few months ago so it’s not a new problem AFAIK)

Thing is, System.Exec is way faster than calling a python script with RunScript. I want to send custom ir commands using irsend to different devices when I press a key. With System.Exec and a shell script everything happens instantly, buy many side-effects occur. With RunScript and a python script that calls subprocess.Popen everything works fine but there is an annoying 0.5-1s delay (very noticeable when I press the same key several times).

Is there any light at the end of the tunnel for this old bug? Or at least any alternative to RunScript that is not THAT slow?

This is a two years old thread btw…

I’m keen to know the answer to trexes question too. Old thread but relevant.

The reason “System.Exec” is fast is because a fork is now very fast in Linux, because of sharing of code. If you don’t have to start a brand new process that isn’t in memory, through Python, you can do things fast.

What you need is some kind of daemon that you can send messages to, and have that daemon send the IR codes. Then, you send the message from Python. You can use Unix sockets, or even a have the daemon be a web server that you send to via HTTP. How you design it is up to you, but the key is to not create a new process every time you want to send one IR code.