RetroPie forum home
    • Recent
    • Tags
    • Popular
    • Home
    • Docs
    • Register
    • Login
    Please do not post a support request without first reading and following the advice in https://retropie.org.uk/forum/topic/3/read-this-first

    How NOT to kill a background process with CTRL-C?

    Scheduled Pinned Locked Moved Help and Support
    terminalctrl-c
    2 Posts 1 Posters 459 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • S
      sleve_mcdichael
      last edited by sleve_mcdichael

      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 of bash 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, before emulationstation #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 with watch -n1 vcgencmd measure_temp and while running emulationstation 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:~ $ 
      
      1 Reply Last reply Reply Quote 0
      • S
        sleve_mcdichael
        last edited by

        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.

        1 Reply Last reply Reply Quote 0
        • First post
          Last post

        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.