Bash tricks

From wikinotes
Revision as of 23:32, 8 February 2021 by Will (talk | contribs) (→‎Simple Menu)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

raw output

Sometimes when parsing shell output, it is useful to see the actual raw output before colours/escape sequences are applied in order to diagnose issues. In this instance, you can pipe a command to cat.

( ls -l  ;  ls -l --color=always  ) | cat -vet

total 41624$
drwxr-xr-x 2 will will     4096 Dec  2 08:01 new$
-rw-r--r-- 1 will will 42557440 Dec  2 08:01 old.tar$
total 41624$
drwxr-xr-x 2 will will     4096 Dec  2 08:01 ^[[01;34mnew^[[0m$
-rw-r--r-- 1 will will 42557440 Dec  2 08:01 old.tar$

Find the Number of tokens in a line:

VAR='some/string/with words'
echo $VAR | tr -cd  "/" | wc -c

Simple Menu

Consider using ncurses or dialog instead before implementing your own menu.
The following should also work.

options=(
    "1- this"
    "2- is"
    "3- a"
    "4- test"
)


executeMenu() {
    # substitute with command to execute for each menu
    echo "ENTERING MENU $1"
}


selectionMenu() {
    #create array from argument
    menu=("${@}")

    #ensure argument is present
    if [ "${menu[0]}" == "" ] ; then
        echo "Error: selectionMenu() requires an array as an argument"
        exit 0
    fi

    # variables
    local menuSize=$(echo ${#menu[@]} - 1 | bc -l)  # size of menu array
    local selLine=0                                 # selected Menu Line
    selBttn=""                                      # button pushed from menu
    initMenu=1                                      # first run of current menu=true

    printMenu() {
        clear
        case $selBttn in
            q) 
                quit=1
                exit 0
                ;;
            k|p) 
                ((selLine--))
                ;;
            j|n) 
                ((selLine++))
                ;;
            '' ) 
                #otherwise menu is entered on first load
                if [ "$initMenu" != "1" ] ; then
                    initMenu=1
                    executeMenu "$selLine"
                fi
                ;;
        esac
        initMenu=0
    
        #restrict menu selection to available menu options
        if [ "$selLine" -gt "$menuSize" ] ; then
            selLine=$menuSize
        elif [ "$selLine" -lt "0" ] ; then
            selLine=0
        fi

        #print menu to screen
        for i in $( seq 0 $menuSize ) ; do
            if [ "$selLine" == "$i" ] ; then
                echo "* ${menu[$i]}"
            else
                echo "  ${menu[$i]}"
            fi
        done

        #read single char input
        read -n 1 selBttn
        printMenu
    }
    if [ "$quit" != "1" ] ; then
        printMenu
    fi
}    

selectionMenu "${options[@]}"