RetroPie forum home
    • Recent
    • Tags
    • Popular
    • Home
    • Docs
    • Register
    • Login

    shell scripting topic

    Scheduled Pinned Locked Moved Ideas and Development
    shellshell scriptprogramming
    191 Posts 10 Posters 84.5k 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.
    • hiulitH
      hiulit @meleu
      last edited by

      @meleu Yeah, you're right. Pixel theme images look fine on my 1920x1080 monitor. I'll try it! ;)

      My little contributions to the RetroPie project:

      • Shell-Script-Boilerplate
      • Fun-Facts-Splashscreens
      • Limit-Last-Played-Games
      1 Reply Last reply Reply Quote 0
      • hiulitH
        hiulit
        last edited by

        I've created this little script to format all theme.xml from a given EmulationStation theme with 4 spaces. It's really unnecessary, but I'm that kind of person :P

        Here it goes:

        #!/usr/bin/env bash
        
        THEME="pixel"
        
        for folder in "/etc/emulationstation/themes/$THEME/"*; do
            if [[ -d "$folder" ]]; then
                if [[ -f "$folder/theme.xml" ]]; then
                    cp "$folder/theme.xml" "$folder/theme-backup.xml"
                    xmlstarlet fo -s 4 "$folder/theme.xml" > "$folder/theme-indent.xml"
                    sed -i '/\?xml/d' "$folder/theme-indent.xml"
                    cp "$folder/theme-indent.xml" "$folder/theme.xml"
                    rm "$folder/theme-indent.xml" "$folder/theme-backup.xml"
                fi
            fi
        done
        

        My little contributions to the RetroPie project:

        • Shell-Script-Boilerplate
        • Fun-Facts-Splashscreens
        • Limit-Last-Played-Games
        1 Reply Last reply Reply Quote 1
        • hiulitH
          hiulit
          last edited by

          When you have a dialog inside a dialog inside a dialog (and so on...), can the "Cancel" button act as a "Back" button? I know the label can be changed, but when you click it it goes back to the first dialog :(

          My little contributions to the RetroPie project:

          • Shell-Script-Boilerplate
          • Fun-Facts-Splashscreens
          • Limit-Last-Played-Games
          meleuM 1 Reply Last reply Reply Quote 0
          • meleuM
            meleu @hiulit
            last edited by meleu

            @hiulit there's no "dialog inside a dialog". You execute a dialog and when you choose the "OK" or "Cancel" button the dialog finishes.

            What causes that impression of a "dialog inside a dialog" is usually a dialog being called one right after another, each one inside its own while loop structure.

            The example I have to show is one of my codes that I am least proud of when it comes to well-written code, but well, let's try...

            Check the rpie-art code here: https://github.com/meleu/rpie-art/blob/master/rpie-art.sh

            This while loop in main_menu() contains the first dialog. Depending on the option, the script calls another function which has another dialog. Let's follow the uninstall_art_menu() flow.

            When the user choose X on the main_menu(), the script calls the uninstall_art_menu() function which has another dialog where you can:

            1. Choose Cancel: the logic flow returns to main_menu() and that loop calls the main_menu()'s dialog again.
            2. Choose a valid option. Which calls another function which has another dialog and the chain-of-dialogs goes on...

            Eh... I'm not sure if I explained well. 😅

            Read, check the code and reread. If you still don't understand feel free to ask. ;-)

            • Useful topics
            • joystick-selection tool
            • rpie-art tool
            • achievements I made
            hiulitH 1 Reply Last reply Reply Quote 1
            • hiulitH
              hiulit @meleu
              last edited by

              @meleu Thanks! That's what I thought. I'll create some functions then, as you did ;)

              My little contributions to the RetroPie project:

              • Shell-Script-Boilerplate
              • Fun-Facts-Splashscreens
              • Limit-Last-Played-Games
              1 Reply Last reply Reply Quote 0
              • hiulitH
                hiulit
                last edited by

                Hi there!
                Can somebody help me figure this out?

                I have an argument passed to a shell script fun-facts-splashscreens.sh --create-fun-fact that can have:

                • no options
                • 1 option [system]
                • 2 options [system rom]

                How can I write a help message? --create -fun-fact [] [system] [system rom]?

                Thanks!

                My little contributions to the RetroPie project:

                • Shell-Script-Boilerplate
                • Fun-Facts-Splashscreens
                • Limit-Last-Played-Games
                mituM 1 Reply Last reply Reply Quote 0
                • mituM
                  mitu Global Moderator @hiulit
                  last edited by

                  @hiulit Add a -h option and display the help when this option is passed to the script.

                  hiulitH 1 Reply Last reply Reply Quote 0
                  • hiulitH
                    hiulit @mitu
                    last edited by

                    @mitu I'm sorry, I didn't explain myself clearly enough.

                    I already have a -h option that shows all the options available. What I meant is, how should I tell the user that the option --create-fun-fact can have:

                    • no options
                    • 1 option [system]
                    • 2 options [system rom]

                    That's what I've come up with: --create-fun-fact [] [system] [system rom]
                    Is that correct?

                    Did I explain myself better this time? :P

                    My little contributions to the RetroPie project:

                    • Shell-Script-Boilerplate
                    • Fun-Facts-Splashscreens
                    • Limit-Last-Played-Games
                    mituM meleuM 2 Replies Last reply Reply Quote 0
                    • mituM
                      mitu Global Moderator @hiulit
                      last edited by

                      @hiulit said in shell scripting topic:

                      --create-fun-fact [] [system] [system rom]

                      Ah, ok. I think the correct syntax would be

                      --create-fun-fact [SYSTEM] [ROM]
                      

                      Usually an argument in brackets ([arg]) means the argument is optional.

                      hiulitH 1 Reply Last reply Reply Quote 0
                      • hiulitH
                        hiulit @mitu
                        last edited by

                        @mitu I see! And if an argument is NOT optional? I have some of those around :P

                        My little contributions to the RetroPie project:

                        • Shell-Script-Boilerplate
                        • Fun-Facts-Splashscreens
                        • Limit-Last-Played-Games
                        mituM 1 Reply Last reply Reply Quote 0
                        • mituM
                          mitu Global Moderator @hiulit
                          last edited by

                          @hiulit If it's not optional, just remove the brackets.

                          --create-fun-fact system [rom]
                          
                          1 Reply Last reply Reply Quote 0
                          • meleuM
                            meleu @hiulit
                            last edited by meleu

                            @hiulit can you explain the use case and provide some examples?

                            I'm sure we can find ways to make an option have zero, one or two options, but from a user point of view I think it's a bit confusing.

                            EDIT:
                            I can't see what would be the use for --create-fun-fact system rom, but if it's intended to be used on RetroPie, you can detect the system by looking the directory where the rom is located.

                            • Useful topics
                            • joystick-selection tool
                            • rpie-art tool
                            • achievements I made
                            hiulitH 1 Reply Last reply Reply Quote 0
                            • hiulitH
                              hiulit @meleu
                              last edited by

                              @meleu I'll try to explain myself even better than the last time :P Here we go!

                              This all comes from the fun-facts-splashscreens-runcommand-onend.sh that has these lines:

                              SYSTEM="$1"
                              ROM_PATH="$3"
                              sudo "$SCRIPT_DIR/fun-facts-splashscreens.sh" --create-fun-fact "$SYSTEM" "ROM_PATH"
                              

                              This is what creates the launching images when stoping the game. This is something the user doesn't need to care about. But then I already had --create-fun-fact in the help message so I wanted to let the user use it, like this:

                              • --create-fun-fact with no options passed creates a boot splashscreen.
                              • --create-fun-fact [SYSTEM] (SYSTEM can be all or any RetroPie system) creates launching images for all the systems, or the given system with the system's logo (and console if it exists).
                              • --create-fun-fact [SYSTEM] [ROM] (ROM can be an absolute path or just the ROM's name + ext, and then it takes the given system to look for the path) creates a launching image for the game.

                              Examples:

                              • --create-fun-fact
                              • --create-fun-fact all
                              • --create-fun-fact megadrive
                              • --create-fun-fact megadrive "/home/RetroPie/megadrive/Sonic the Hedgehog.zip"
                              • --create-fun-fact megadrive "Sonic the Hedgehog.zip"

                              I can see that from the user's perspective it could be a little confusing... Maybe it's better to split --create-fun-fact into two separate functions --create-fun-fact-boot-splashscreen and --create-fun-fact-launching-images.

                              Maybe I should remove this option from the help message? Just have it for myself to test?
                              That's something that can be done via the GUI, btw:

                              0_1522918743191_2018-04-03-181738_727x465_scrot.png

                              1_1522918743201_2018-04-03-181800_727x465_scrot.png

                              My little contributions to the RetroPie project:

                              • Shell-Script-Boilerplate
                              • Fun-Facts-Splashscreens
                              • Limit-Last-Played-Games
                              meleuM 1 Reply Last reply Reply Quote 0
                              • meleuM
                                meleu @hiulit
                                last edited by

                                @hiulit You wouldn't want to create a launching image for Sonic using a NES splashscreen, would you? Well, my suggestion below does not have this kind of flexibility, but here it go:

                                help message

                                --create-fun-fact [system|path/to/a/ROM]     no arguments = create boot splashscreen
                                                                             system = create a launching image for system
                                                                             ROM = create a launching image for a ROM
                                

                                If you wanna use this approach, please write a better help message for this option! ;)

                                code

                                #!/bin/bash
                                
                                user="$SUDO_USER"
                                [[ -z "$user" ]] && user="$(id -un)"
                                home="$(eval echo ~$user)"
                                
                                readonly RP_DIR="$home/RetroPie"
                                readonly RP_ROMS_DIR="$RP_DIR/roms"
                                readonly RP_CONFIG_DIR="/opt/retropie/configs"
                                
                                function get_options() {
                                
                                    case "$1" in
                                
                                #H --create-fun-fact [system|path/to/a/ROM]     no arguments = create boot splashscreen
                                #H                                              system = create a launching image for system
                                #H                                              ROM = create a launching image for a ROM
                                        --create-fun-fact)
                                            if [[ -z "$2" ]]; then
                                                # NOTE: for this usecase the --create-fun-fact MUST be the
                                                #       last parameter used in the command line.
                                                echo "Let's create a boot splashscreen with a fun fact!"
                                
                                            elif [[ -f "$2" ]]; then
                                                # NOTE: if it's a regular file, let's check if it's a ROM and
                                                #       create a splashscreen for this game.
                                                local rom_full_path="$(realpath "$2")"
                                
                                                if [[ "$rom_full_path" != "$RP_ROMS_DIR"* ]]; then
                                                    echo "ERROR: \"$2\" is not on a valid ROM directory" >&2
                                                    exit 1
                                                fi
                                
                                                # Reference for the tricks used to get the system's name below:
                                                # http://www.tldp.org/LDP/abs/html/parameter-substitution.html#PSOREX2
                                                system="${rom_full_path#$RP_ROMS_DIR/}"
                                                system="${system%/*}"
                                
                                                echo "Let's create a launching image for \"$2\" using the ${system}'s one!"
                                
                                            elif [[ -d "$RP_CONFIG_DIR/$2" ]]; then
                                                echo "Let's create a launching image for \"$2\" system!"
                                
                                            else
                                                echo "ERROR: \"$2\": invalid argument." >&2
                                                exit 1
                                            fi
                                            ;;
                                
                                #H --help                                       Print the help message and exit.
                                        --help|-h)
                                            sed '/^#H /!d; s/^#H //' "$0"
                                            echo
                                            exit 0
                                            ;;
                                    esac
                                }
                                
                                get_options "$@"
                                

                                testing

                                $ ./cff.sh --create-fun-fact
                                Let's create a boot splashscreen with a fun fact!
                                
                                $ ./cff.sh --create-fun-fact abcd
                                ERROR: "abcd": invalid argument.
                                
                                $ ./cff.sh --create-fun-fact nes
                                Let's create a launching image for "nes" system!
                                
                                $ ./cff.sh --create-fun-fact ~/RetroPie/roms/nes
                                ERROR: "/home/meleu/RetroPie/roms/nes": invalid argument.
                                
                                $ ./cff.sh --create-fun-fact ~/RetroPie/roms/nes/Contra\ \(USA\).zip 
                                Let's create a launching image for "/home/meleu/RetroPie/roms/nes/Contra (USA).zip" using the nes's one!
                                
                                • Useful topics
                                • joystick-selection tool
                                • rpie-art tool
                                • achievements I made
                                hiulitH 1 Reply Last reply Reply Quote 0
                                • hiulitH
                                  hiulit @meleu
                                  last edited by hiulit

                                  @meleu Thanks for your reply! And no, I wouldn't want that

                                  launching image for Sonic using a NES splashscreen
                                  But my script prevents from doing that.

                                  I'll try to paste every piece of code that I have, because it's very similar to what you have:

                                  -cff|--create-fun-fact)
                                      is_fun_facts_empty
                                      if [[ -z "$2" ]]; then
                                          create_fun_fact
                                      else
                                          shift
                                          create_fun_fact "$@"
                                          shift
                                      fi
                                      ;;
                                  

                                  If no arguments are passed called create_fun_fact without arguments, if there are any arguments, pass them all.

                                  function create_fun_fact() {
                                      if [[ -z "$1" ]]; then
                                          create_fun_fact_boot
                                      else
                                          create_fun_fact_launching "$@"
                                      fi
                                  }
                                  

                                  There's more things going one here, but it basically calls one function or another depending on if there are arguments.
                                  create_fun_fact_boot is self explanatory.
                                  create_funfact_launching takes all the arguments and then:

                                  function create_fun_fact_launching() {
                                      local system="$1"
                                      local rom_path="$2"
                                  
                                      if [[ "$system" == "all" ]]; then
                                          // Loop all systems and call create_fun_fact_launching "$system"
                                      else
                                          if [[ -n "$rom_path" ]]; then
                                              // Check if $system it's the same in "rom_path"
                                              if true
                                                  // Create launching image for the game
                                              else
                                                  // Create launching image for the system
                                          else
                                              // Create launching image for the system
                                          fi
                                      fi
                                  }
                                  

                                  More or less that what I do. I think it's similar of what you wrote.

                                  But then again, I think maybe it's better to to have 2 separate options:

                                  • --create-fun-facts-boot-splashscreen(doesn't accept any argument)
                                  • --create-fun-facts-launching-images (accepts system and rom)

                                  EDIT:
                                  You can take a look for youself https://github.com/hiulit/RetroPie-Fun-Facts-Splashscreens/blob/new-gui-menu/fun-facts-splashscreens.sh ;)

                                  My little contributions to the RetroPie project:

                                  • Shell-Script-Boilerplate
                                  • Fun-Facts-Splashscreens
                                  • Limit-Last-Played-Games
                                  1 Reply Last reply Reply Quote 0
                                  • meleuM
                                    meleu
                                    last edited by

                                    I've just found this and decided to share here:

                                    Pure Bash Bible

                                    The goal of this book is to document known and unknown methods of doing various tasks using only built-in bash features. Using the snippets from this bible can help remove unneeded dependencies from scripts and in most cases make them faster.

                                    • Useful topics
                                    • joystick-selection tool
                                    • rpie-art tool
                                    • achievements I made
                                    cyperghostC 1 Reply Last reply Reply Quote 2
                                    • cyperghostC
                                      cyperghost @meleu
                                      last edited by cyperghost

                                      @meleu Wow this is really helpfull ;) Cool snippets for bash coders. Thank you so much.

                                      For ex:
                                      Reverse array I did

                                      for ((z=${#array[*]}-1; z>-1; z--)); do
                                             echo "${array[z]}"
                                      done
                                      

                                      Reverse array with the bash-bible

                                      ## Reverse an array
                                      
                                      # ```sh
                                      reverse_array() {
                                          # Usage: reverse_array "array"
                                          shopt -s extdebug
                                          f()(printf '%s\n' "${BASH_ARGV[@]}"); f "$@"
                                          shopt -u extdebug
                                      }
                                      # ```
                                      

                                      Up to now my version seems a bit less complex. Maybe it's due my limited coding skills. I'm still learning ....

                                      1 Reply Last reply Reply Quote 0
                                      • cyperghostC
                                        cyperghost
                                        last edited by cyperghost

                                        @meleu I think that's just a note to me ... BashPitfalls

                                        function1(){
                                            local status=$(false)
                                            echo $?
                                        }
                                        

                                        Will return 0 which is obviously wrong
                                        So the return code 0 just indicates the correct setting of a local setted value, which was correctly done ;)

                                        So to get out of this make following

                                        function1(){
                                            local status
                                            status=$(false)
                                            echo $?
                                        }
                                        

                                        This will put out correct value for "error" 1

                                        That's all folks

                                        meleuM 1 Reply Last reply Reply Quote 1
                                        • meleuM
                                          meleu @cyperghost
                                          last edited by

                                          @cyperghost yeah, that's a thing to be careful. I learned it while reading the RetroPie's Shell Style Guide: https://retropie.org.uk/docs/Shell-Style-Guide/#use-local-variables

                                          • Useful topics
                                          • joystick-selection tool
                                          • rpie-art tool
                                          • achievements I made
                                          1 Reply Last reply Reply Quote 0
                                          • meleuM
                                            meleu
                                            last edited by

                                            I would like to share a little trick I learned today and also ask for some help...

                                            First the short story

                                            I was needing to check if the current hour is after 18h, then I tried this:

                                            hour=$(date +%H)
                                            if [[ $hour -gt 18 ]]; then
                                                echo "do something..."
                                            fi
                                            

                                            And then I got this error (please, forgive the non-english):

                                            -bash: [[: 08: valor muito grande para esta base de numeração (token de erro é "08")
                                            

                                            As you can see, the problem is that date +%H returns 08, and when I try to compare it, bash doesn't see 08 as a decimal number.

                                            The solution is obviously getting rid of that leading zero. I decided that using sed would be overkill for such a simple task, then I've found a pure bash solution using a feature of $(( )).

                                            hour=$(date +%H)
                                            hour=$(( 10#$hour ))  # could also be an oneliner: $(( 10#$(date +%H) ))
                                            if [[ $hour -gt 18 ]]; then
                                                echo "do something..."
                                            fi
                                            

                                            And now my script is working perfectly!

                                            Now the help I mentioned earlier on the beginning of this post...

                                            On that stackoverflow answer I see this:

                                            The $(( )) sets up an arithmetic context and the 10# converts the number from base 10 to base 10 causing any leading zeros to be dropped.

                                            Alright, but I like to see stuff on the official documentation in a hope to learn more tricks. The $(( )) is a bash builtin feature, but in the official documentation there's no mention to the 10# operand.

                                            Any thoughts on where to get info about it?

                                            • Useful topics
                                            • joystick-selection tool
                                            • rpie-art tool
                                            • achievements I made
                                            SanoS 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.