How NOT to kill a background process with CTRL-C?
-
Sometimes I quit ES and leave the terminal up when I'm not using it. And sometimes I want to start up ES from the couch with my wireless controller, rather than cross the room and use the keyboard. (I know, right?)
...anyway, I thought I had it solved with jslisten (watches
/dev/input/js{n}
for a predefined button combo & runs a command on activation):https://github.com/workinghard/jslisten
How I've set it up:
To activate it when I quit ES, I add this line to
~/.bashrc
:[[ "$(tty)" == "/dev/tty1" ]] && (/opt/retropie/configs/all/jslisten/jslisten /dev/input/js0 &)
...it is configured to watch for my button combo and then run a script I've called
logmeout.sh
that looks for and kills the oldest instance ofbash
on tty1:#!/bin/bash pid="$(pgrep -o -t tty1 bash)" [[ -n "$pid" ]] && kill "$pid"
And then, to disable it at login, I add
pkill jslisten
to/opt/retropie/configs/all/autostart.sh
, beforeemulationstation #auto
is invoked.This is mostly working as intended. I can pick up my controller from across the room, press select + guide + start and, as long as it was just sitting at the terminal, I'll be logged out, at which point the autostart triggers and logs me back in to EmulationStation. Just like I wanted.
On the other hand if it is NOT just sitting at the terminal (I've tested while editing a file in
nano
, while watching system temp withwatch -n1 vcgencmd measure_temp
and while runningemulationstation
manually from command line), nothing happens; the current task is not interrupted and when I finish it, I am not suddenly logged out or anything bad like that. Also just like I wanted.There's just one little thorn left I have to work out. Sometimes it just...doesn't do anything. I'll push the buttons and nothing happens. Unplug and replug the controller's wireless dongle, nothing. After a quick relog from the keyboard, everything is working again...weird.
The next time it happened I thought to check the running processes with ps, and the
jslisten
process was not listed. So why not......I tracked it down to any time I hit ctrl-c in the terminal, it's killing the process. Why? And what can I do about it?
Also this only happens when it's started from
.bashrc
; if I run the exact same command from terminal and ctrl-c, the process persists (terminal output re-enactment):# {quit from EmulationStation} pi@retropie:~ $ ps PID TTY TIME CMD 13883 tty1 00:00:00 bash 14115 tty1 00:00:09 jslisten 16286 tty1 00:00:00 ps pi@retropie:~ $ ^C pi@retropie:~ $ ps PID TTY TIME CMD 13883 tty1 00:00:00 bash 16300 tty1 00:00:00 ps pi@retropie:~ $ [[ "$(tty)" == "/dev/tty1" ]] && (/opt/retropie/configs/all/jslisten/jslisten /dev/input/js0 &) pi@retropie:~ $ ps PID TTY TIME CMD 13883 tty1 00:00:00 bash 16339 tty1 00:00:00 jslisten 16340 tty1 00:00:00 ps pi@retropie:~ $ ^C pi@retropie:~ $ ps PID TTY TIME CMD 13883 tty1 00:00:00 bash 16339 tty1 00:00:00 jslisten 16341 tty1 00:00:00 ps pi@retropie:~ $
-
In case anyone's keeping track, Reddit user McDutchie says:
Ctrl+C interrupts all the processes in the current process group. When your [jslisten] is invoked from .bashrc, I think you'll find it shares a process group ID with bash itself. You can check this with:
ps -o pid -o pgid -o comm
The -m option, a.k.a. -o monitor, causes bash to give background processes (including those invoked from a subshell, as you're doing) their own process group, so that Ctrl+C does not interrupt them. This option is on by default for interactive shells, but profile scripts are run before bash turns it on. But you can turn it on yourself within the subshell that you're invoking the background process from:
[[ "$(tty)" == "/dev/tty1" ]] && (set -m; /opt/retropie/configs/all/jslisten/jslisten /dev/input/js0 &)
This does indeed seem to be my solution. Ctrl-c (for example, to cancel a half-typed command when I notice a typo at the beginning) no longer kills the
jslisten
process, allowing my "logout hotkey combo" to remain functional.
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.