How to cleanly stop emulationstation from the command line
-
Hi,
I wrote a few bash functions to be able to switch between Kodi, emulationstation, and raspbian. I plan to incorporate them into my homebridge setup so that I can control them via Siri.
I've been using
pkill emulationstatio
to stop emulationstation, but I discovered yesterday that this is not completely sufficient. I had a game paused when I stopped emulationstation using my bash function and the pause screen didn't go away (even though there were no emulationstatio processes shown byps -el
).Plus, killing processes seems pretty drastic, so I was wondering if anyone knows a clean way to stop emulationstation and any currently running emulators from the command line? I was just about to request this as a feature on the github repo after not finding anything in the documentation, but it said I should post here first.
If there's not a way to do this that's supported, I could try coding up something using
ps -s
in order to kill any child processes it shows...Thanks,
Rob -
Why would you need to use
kill
to switch between the 3 ? You can install Kodi and the Desktop in RetroPie and start them from Emulationstation, once you exit one of them, you're back in Emulationstation.There is a script, created by @cyperghost (hello there !), that detects if any emulators are started from Emulationstation and stop them before stopping Emulationstation - https://github.com/crcerror/ES-generic-shutdown.
-
@hepcat72 Yes there is a script
Command line parameter are:
--es-pid
Shows PID of ES, if not it shows 0- -
-rc-pid
Shows PID of runcommand.sh - shows 0 if not found --es-closeemu
Tries to shutdown emulators, with cyperghost method- -
-es-poweroff
Shutdown emulators (if running), Closes ES, performs poweroff --es-reboot
Shutdown emulators, Cloese ES, performs system reboot--es-restart
Shutdown emulators (if running), Restart ES
-
I didn't say I needed to kill any of them. I simply don't want to run them concurrently. And I want to switch between them (by stopping one and starting the other) using a command-line executable so that I can do it via homebridge (i.e. Siri) or Node-RED instead of using the keyboard or game controller.
kill
was just the only way I knew of to do that.In fact, that's what the script you linked me to appears to do. (Thanks for that!) It uses
kill
and even does it in the way I imagined I would do it (if there wasn't already a pre-made script) - by grabbing all the child PIDs of emulationstation. Though it looks like it assumes you've started emulationstation via a script calledruncommand.sh
, so I suspect I may need to make a few modifications to serve my purposes. It finds child processes by recursively looping on the output ofpgrep -P
. I was going to use the session ID with a single command line call ofps
with-s
(though not everything has a session ID - I'd have to look and see whether es does).The script is pretty well tricked out and supports much more than what I've got. It's good to have confirmation that how I was thinking of doing it is how others have done it.
Do you know if there's a more graceful way to stop ES from the command line without killing it?
-
@hepcat72 I think you may be reading the script wrong - the
runcommand.sh
script is launched from Emulationstation when any emulator is started, so that's why the script looks for it.Do you know if there's a more graceful way to stop ES from the command line without killing it?
No, there isn't. On Unix/Linux though, sending a signal via
kill
is a perfectly acceptable way to communicate with a process. In fact, sending theTERM
signal to Emulationstation (while no emulators are running), makes Emulationstation cleanly shut down. -
@mitu Ah, OK. That makes sense. I also didn't know whether emulationstation was catching the
TERM
signal. I assumed it wasn't since the emulator was still going, but upon thinking about it, to get to that menu manually, you have to have already stopped the emulator, so that makes a bit of sense. I suppose it would be nice if it checked for running emulators upon receivingTERM
. -
@hepcat72 It's not that simple - once Emulationstation launches an emulator, it's basically paused. That's the reason the script I mentioned at the start first stops any emulators before stopping Emulationstation.
-
I suppose it would be nice if it checked for running emulators upon receiving TERM.
The script checks the SIGTERM (kill -15) always. It waits for about 2-3 seconds if the obtained PID is active. If yes then it sends SIGKILL (kill -9) and this will abort the emulator. So the SIGTERM is a proper exit, if this fails SIGKILL will abort the process (not recommended but sometimes needed)
But it is so like @mitu already wrote. The entrypoint of the chain is the
runcommand.sh
script and it will always check for an instance of runcommand and that means there is an emulator active. If not then you are in ES main screen and then ES can be shut down. It is a bit of mess how this works but it is the most flexible way and it works best. -
@mitu Right, so you're saying it's unable to catch a signal while it's "paused". Makes more sense now. I had assumed it would have forked the emulator and thus be ready for interrupt signals to act on in the background.
Anyway, this is way more than I really have any business knowing. Graphics and GUIs have never been my thing and I know enough about inter-process communication to get me into trouble, but that's about it. Thanks for the help. Really useful.
Contributions to the project are always appreciated, so if you would like to support us with a donation you can do so here.
Hosting provided by Mythic-Beasts. See the Hosting Information page for more information.