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

    [Solved] How to bind a shell command to a hotkey? (raspi2png)

    Scheduled Pinned Locked Moved Help and Support
    hotkeyshortcutscreenshotraspi2png
    59 Posts 6 Posters 11.7k 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.
    • ClydeC
      Clyde
      last edited by

      @mitu Sorry about the late answer, I don't have much time at the moment. I'll look into triggerhappy this weekend.

      @hermit You'll have to put @Lolonois' commands in brackets following a $ and remove the two + after basename and before .png:

      ./raspi2png --pngname $(basename `ps a|grep RetroPie/roms/|head -1|awk '{ print $NF }'`).png
      

      This will creat a screenshot called gamename.ext.png, e.g. gorf.zip.png. If you want to remove the zip extension, add -s .zip as an option to basename:

      ./raspi2png --pngname $(basename -s .zip `ps a|grep RetroPie/roms/|head -1|awk '{ print $NF }'`).png
      
      1 Reply Last reply Reply Quote 1
      • H
        hermit
        last edited by

        thank you all, but I give up
        the only result was a file with a type name: _NCE72 ~ 2.PNG

        ClydeC 1 Reply Last reply Reply Quote 0
        • ClydeC
          Clyde @hermit
          last edited by

          @hermit It seems like this method has problems with spaces in the filename, because awk will treat them as field separators, and thus handing over only the part of the filename after the last space in it (I think, as I'm not very experienced in awk).

          Could you test it with a rom filename without spaces?

          H 1 Reply Last reply Reply Quote 0
          • H
            hermit @Clyde
            last edited by

            @Clyde Could you test it with a rom filename without spaces?

            yes :)
            I have rename "Super Mario World 2 - Yoshi's Island (Europe) (En,Fr,De) (Rev 1).zip" in 000super_mario_world2.zip and the result was: 000super_mario_world2.png

            but normally the roms have spaces ... :(

            ClydeC 1 Reply Last reply Reply Quote 0
            • ClydeC
              Clyde @hermit
              last edited by Clyde

              @hermit My dirty hack solution after some reading:

              raspi2png --pngname $(basename -s .zip `ps a|grep RetroPie/roms/|head -1|sed -e 's/ /_/g'|awk '{ print $NF }'|sed 's/\\\//g'`).png
              

              I inserted the command sed -e 's/ /_/g' before awk to convert any whitespace to an underscore, and a sed 's/\\\//g' after awk to remove any \ which the Linux shell uses to mark special characters like whitespaces,', (, ) etc.

              I did it this way because awk seems to have problems with whitespaces (thus sed removes them beforehand), but also needs the backslash before special characters (thus sed removes them only afterwards).

              I sometimes can't let unsolved problems just go … although I now have to hurry cleaning up my flat before going to a party. 😌

              edit: See @mitu's optimised version with whitespace-passthrough and multiple filename extensions support here.

              1 Reply Last reply Reply Quote 0
              • H
                hermit
                last edited by

                @Clyde perfect :) tested with both snes and amiga :) Thanks a lot :)

                thank you all :)

                1 Reply Last reply Reply Quote 0
                • ClydeC
                  Clyde
                  last edited by Clyde

                  Okay, I finally got around working on this. Here's my tested solution:

                  1. Install triggerhappy:
                  sudo apt install triggerhappy
                  
                  1. Change its service configuration file using sed to run it as user pi for writing permissions in that user's $HOME directory (optional, but needed for the example below):
                  sudo sed -i -e 's/nobody/pi/' /etc/systemd/system/multi-user.target.wants/triggerhappy.service
                  
                  1. Use thd to find the code of the key you want to connect a shell command to:
                  thd --dump /dev/input/*      # exit with CTRL+C
                  
                  1. Put the code and the desired shell command into a fittingly named file in the directory /etc/triggerhappy/triggers.d/
                    Example: Running the raspi2png command from above on the press of "Print Screen", using the config file /etc/triggerhappy/triggers.d/raspi2png.conf:
                  KEY_SYSRQ 1 raspi2png --pngname "/home/pi/$(ps a | grep RetroPie/roms | awk -F "/" 'NR==1 { print $NF }' | sed 's/\.[^.]*$//g; s/\\//g')"-$(date +%Y.%m.%d-%H.%M.%S).png
                  
                  • KEY_SYSRQ is the code for the "Print Screen" key on most standard keyboards.
                  • "1" = pressing the key, "2" = holding the key down, "0" = releasing the key
                  • The rest is the command or script to run in this event. You may have to add the path to your raspi2png if it's not in your shell's search path like /home/pi/bin is for example.
                  • Optional: Put the command in a shell script and run the script from the .conf file. See @roslofs post below. This may be advisable for multiple commands or if you change them from time to time, sparing you the reloading of the demon (see #4).
                  1. Reload the service to apply the changes:
                  sudo systemctl daemon-reload                 # reload the changes in triggerhappy.service
                  sudo systemctl restart triggerhappy.service  # reload the changes in /etc/triggerhappy/triggers.d/
                  

                  Now, in the above example, pressing "Print Screen" should save a screenshot named after the currently running ROM file in the directory /home/pi/.

                  Comments, test results, corrections, and enhancements are welcome. :)

                  edit: You can check the status and any error messages of the triggerhappy daemon with the command sudo systemctl status triggerhappy.service.
                  edit 2: Changed the raspi2png command to @mitu's optimised version.
                  edit 3: Added @mitu's correction and @roslofs script variant.

                  mituM 1 Reply Last reply Reply Quote 3
                  • ClydeC
                    Clyde
                    last edited by

                    Credits go to @mitu, @Zigurana, @Djon, and @Headrush69 for their groundwork in https://retropie.org.uk/forum/topic/2377/control-volume-through-retroarch-with-keyboard and https://retropie.org.uk/forum/topic/18133/triggerhappy-daemon-thd-doesn-t-work-on-my-pi-running-retropie-help.

                    1 Reply Last reply Reply Quote 0
                    • mituM
                      mitu Global Moderator @Clyde
                      last edited by mitu

                      @Clyde Hey, you got it working - great stuff !

                      Now, the suggestions :) :

                      • You can probably replace the long line of
                      `ps a|grep RetroPie/roms/|head -1|sed -e 's/ /_/g'|awk '{ print $NF }'|sed 's/\\\//g'`
                      

                      with something like

                      ps a | grep RetroPie/roms | head -1 | awk -F "/" '{ print $NF }'
                      

                      This will get you the last path segment (which can be a file or folder) from the line containing the ROM path.

                      EDIT: this will also preserve whitespaces in the filename, so it's not a drop-in replacement for the original command.

                      • You're assuming the ROM is a .zip, but that not might be the case. Can't think of a simple and elegant way of dealing with this but I have an idea.
                      ClydeC 1 Reply Last reply Reply Quote 2
                      • ClydeC
                        Clyde @mitu
                        last edited by Clyde

                        @mitu I already played around with awk -F but I got no good results.

                        raspi2png --pngname /home/pi/$(basename -s .zip `ps a | grep RetroPie/roms/ | head -1 | awk -F "/" '{ print $NF }'`).png
                        

                        will save a file called 7th\, whereas my command will save 7th_Saga,_The_(USA).png.

                        edit: I gave up on preserving the whitespaces. :)
                        edit 2: Have to leave for the gym now. I'm curious about your idea about the rom's filename extension.

                        1 Reply Last reply Reply Quote 0
                        • mituM
                          mitu Global Moderator
                          last edited by mitu

                          If you don't quote your argument, spaces will surely be a problem. Anyway, here it is what I got so far.

                          raspi2png --pngname "$(ps a | grep RetroPie/roms | awk -F "/" 'NR==1 { print $NF }' | sed 's/\.[^.]*$//g')"-$(date +%Y.%m.%d-%H.%M.%S).png
                          

                          This should work with spaces, regardless of extension, and adds a timestamp at the end. If you'd like to keep the date format the way RetroArch does it, you can use:

                          raspi2png --pngname "$(ps a | grep RetroPie/roms | awk -F "/" 'NR==1 { print $NF }' | sed 's/\.[^.]*$//g')"-$(date +%y%m%d-%H%M%S).png
                          

                          Now, the RetroArch reference got me thinking, so I checked and you can tell RA to take a screenshot with the Network control interface - https://docs.libretro.com/tech/network-control-interface/. Assuming you got RA configured to start this interface (I don't think it's enabled by default, I just have it for the power off/reset buttons), the command to take a screenshot can be just

                          echo -n "SCREENSHOT" | nc -u -w1 127.0.0.1 55355
                          

                          and a screenshot would be saved in ~/.config/retroarch/screenshots (a.k.a. /opt/retropie/configs/all/retroarch/screenshots or \\retropie\configs\all\retroarch\screenshots). You'll need netcat installed to provide the nc command.

                          ClydeC 1 Reply Last reply Reply Quote 1
                          • ClydeC
                            Clyde @mitu
                            last edited by

                            @mitu said in How to bind a shell command to a hotkey? (raspi2png):

                            If you don't quote your argument, spaces will surely be a problem. Anyway, here it is what I got so far.

                            raspi2png --pngname "$(ps a | grep RetroPie/roms | awk -F "/" 'NR==1 { print $NF }' | sed 's/\.[^.]*$//g')"-$(date +%Y.%m.%d-%H.%M.%S).png
                            

                            This still won't get rid of the backslashes, e.g. creating Super\ Mario\ Bros.\ \(2P\ Hack\)-2019.02.23-18.10.44.png. But it does work with the .nes extension of this rom, thanks!

                            raspi2png --pngname "$(ps a | grep RetroPie/roms | awk -F "/" 'NR==1 { print $NF }' | sed 's/\.[^.]*$//g')"-$(date +%y%m%d-%H%M%S).png
                            

                            Same here: Super\ Mario\ Bros.\ \(2P\ Hack\)-190223-181049.png

                            echo -n "SCREENSHOT" | nc -u -w1 127.0.0.1 55355
                            

                            Works like a charm, thanks again for this alternative!

                            1 Reply Last reply Reply Quote 0
                            • mituM
                              mitu Global Moderator
                              last edited by mitu

                              Yes, the dreaded \, forgot about them - I was testing with an emulator started. This can be fixed taking the sed command from your initial line:

                              raspi2png --pngname "$(ps a | grep RetroPie/roms | awk -F "/" 'NR==1 { print $NF }' | sed 's/\.[^.]*$//g; s#\\##g')"-$(date +%Y.%m.%d-%H.%M.%S).png
                              

                              E.T.\ The\ Extra-Terrestrial\ \(1982\)\ \(Atari\)\ \(PAL\)\ \[\!\]-2019.02.23-17.20.15.png becomes E.T. The Extra-Terrestrial (1982) (Atari) (PAL) [!]-2019.02.23-17.25.43.png

                              ClydeC 2 Replies Last reply Reply Quote 1
                              • ClydeC
                                Clyde @mitu
                                last edited by

                                @mitu To answer in German: Wunderbar! 😄

                                1 Reply Last reply Reply Quote 0
                                • ClydeC
                                  Clyde @mitu
                                  last edited by Clyde

                                  @mitu said in How to bind a shell command to a hotkey? (raspi2png):

                                  aspi2png --pngname "$(ps a | grep RetroPie/roms | awk -F "/" 'NR==1 { print $NF }' | sed 's/\.[^.]*$//g; s#\\##g')"-$(date +%Y.%m.%d-%H.%M.%S).png
                                  

                                  You might want to change that to raspi2png with an "r". 😉

                                  edit: Aaaand … I saw your post changing while I was waiting for this post to appear. 😆

                                  mituM 1 Reply Last reply Reply Quote 0
                                  • mituM
                                    mitu Global Moderator @Clyde
                                    last edited by mitu

                                    @Clyde I already did :). Anyway, I think you should add a reference to your solution post to your 1st post, so people can find it without reading to the whole topic.
                                    Now the challenge is to find the equivalent of raspi2png for other platforms (Odroid, Pc).

                                    ClydeC 2 Replies Last reply Reply Quote 0
                                    • ClydeC
                                      Clyde @mitu
                                      last edited by Clyde

                                      @mitu Did you read my mind? I just did that. 😱 😄

                                      edit: Er … sorry, I didn't do that, but added a reference of your raspi2png solution to my first one. Adding the reference that you meant now. 😳

                                      1 Reply Last reply Reply Quote 1
                                      • ClydeC
                                        Clyde @mitu
                                        last edited by

                                        @mitu Done, along with "[Solved]" in the title and my How-To updated with your raspi2png line.

                                        I love communities like this for such constructive synergy. 😊

                                        1 Reply Last reply Reply Quote 0
                                        • roslofR
                                          roslof
                                          last edited by roslof

                                          Love this thread, but I may need a smidgen more help to get this to work.

                                          I followed Clyde's guide to the letter, but after pressing the defined key, entering sudo systemctl status triggerhappy.server yields:

                                          Feb 23 19:01:19 retropie thd[2523]: Executing trigger action: raspi2png --pngname "/home/pi/$(ps a | grep RetroPie/roms | awk -F "/" 'NR==1 { print $NF }' | sed 's/.[^.]*$//g; s <---abruptly ends
                                          Feb 23 19:01:19 retropie thd[2523]: sh: 1: Syntax error: Unterminated quoted string

                                          Looks like it's cutting off the command line... No idea why. It looks fine in the config file. Actually, I just noticed that the line is being cut after EXACTLY 128 characters... So I wager I'm experiencing some character line limit that y'all are not.
                                          Edit: It turned out the character limit was a red herring and not the cause.

                                          FWIW, if I copy the same information from Step 4 into bash (removing KEY_SYSRQ 1) it works fine, and raspi2png takes the shot and the output file is named correctly. So the syntax as provided by Clyde (via Mitu) is definitely correct.

                                          I'm only having trouble w/triggerhappy truncating the line from the config file in triggers.d.

                                          Any advice?

                                          mituM 1 Reply Last reply Reply Quote 0
                                          • mituM
                                            mitu Global Moderator @roslof
                                            last edited by

                                            @roslof If you post the contents of the /etc/triggerhappy/triggers.d/raspi2png.conf we may be able to spot any errors.

                                            roslofR 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.