HiveBrain v1.2.0
Get Started
← Back to all entries
patternbashMinor

Bash menu-driven text file viewer / presenter tool

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
filepresenterbashtextviewermenudriventool

Problem

This is a simple Bash script to provide menu driven manuals and standard operating procedures.

Sops and mans with the extension .sopman.txt will be loaded.

The file motd is required, it is intended to prompt the user with a banner containing useful and or up to date information.

Use the markup +color+ to colorize a line, see colors.sopman.txt for complete list of supported colors.

Github Project

See Find and Replace Question

Powershell Version Code Review

```
#!/usr/bin/env bash
#.-----.-----.-----.--------.---.-.-----.
#|__ --| _ | _ | | _ | |
#|_____|_____| __|__|__|__|___._|__|__|
# |__| Matthew A. Brassey
version=1.0.0

license="
sopman v${version}
Copyright (C) 2017 Matthew A. Brassey

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see .
"

help="
Usage: ./sopman.sh [--help|--version]

[options]
--search Search sopman archive for a string. '--search '
--motd Display message of the day.
--license Show lisense information.
"

#Variables
args=("$@")
sops=(sops/*.sopman.txt)
stoploop="false"
endscript="false"
length="${#sops[@]}"

#Colors
lineColor='\e[0m'
reset="\e[0m";
black="\e[1;30m";
blue="\e[1;34m";
cyan="\e[1;36m";
green="\e[1;32m";
purple="\e[1;35m";
red="\e[1;31m";
white="\e[1;37m";
yellow="\e[1;33m";
header="$(echo -e "${cyan}=======================================

Solution

I don't have time for a full review, but I'll just mention that you seem to have terminal-specific escapes here:

lineColor='\e[0m'
reset="\e[0m";
black="\e[1;30m";
blue="\e[1;34m";
cyan="\e[1;36m";
green="\e[1;32m";
purple="\e[1;35m";
red="\e[1;31m";
white="\e[1;37m";
yellow="\e[1;33m";


Assuming these are supposed to be Linux console escapes, they can be more portably written thus:

reset="$(tput sgr0)"
lineColor="$reset"
black="$(tput bold; tput setaf 0)"
blue="$(tput bold; tput setaf 4)"
cyan="$(tput bold; tput setaf 6)"
green="$(tput bold; tput setaf 2)"
purple="$(tput bold; tput setaf 5)"
red="$(tput bold; tput setaf 1)"
white="$(tput bold; tput setaf 7)"
yellow="$(tput bold; tput setaf 3)"


The above produces real terminal escapes, so you'll be able to drop the non-POSIX -e flag to echo. That's a Good Thing, but you will need to properly quote their expansions.

In GETCOLOR, where these codes are interpolated, there's a very repetitive switch statement:

case $match in
        "+black+") lineColor=$black;;
        "+red+") lineColor=$red;;
        #....
      esac


It looks like it would be easier to just substitute the variable name, using ${! }:

function GETCOLOR() {
    if [[ $1 =~ \+[a-Z]+\+? ]]
    then
        local match="${BASH_REMATCH[0]}"
        case "$match" in
            +black+|+red+|+green+|+blue+|+purple+|+cyan+|+yellow+|+white+)
                match="${match//+}"
                lineColor="${!match}"
                ;;
            *)
                lineColor="$reset"
                ;;
        esac
    fi
}


That can be simplified further, by using a capture group for the word inside +...+:

function GETCOLOR() {
    if [[ $1 =~ \+([a-Z]+)\+? ]]
    then
        local match="${BASH_REMATCH[1]}"
        case "$match" in
            black|red|green|blue|purple|cyan|yellow|white)
                lineColor="${!match}"
                ;;
            *)
                lineColor="$reset"
                ;;
        esac
    fi
}

Code Snippets

lineColor='\e[0m'
reset="\e[0m";
black="\e[1;30m";
blue="\e[1;34m";
cyan="\e[1;36m";
green="\e[1;32m";
purple="\e[1;35m";
red="\e[1;31m";
white="\e[1;37m";
yellow="\e[1;33m";
reset="$(tput sgr0)"
lineColor="$reset"
black="$(tput bold; tput setaf 0)"
blue="$(tput bold; tput setaf 4)"
cyan="$(tput bold; tput setaf 6)"
green="$(tput bold; tput setaf 2)"
purple="$(tput bold; tput setaf 5)"
red="$(tput bold; tput setaf 1)"
white="$(tput bold; tput setaf 7)"
yellow="$(tput bold; tput setaf 3)"
case $match in
        "+black+") lineColor=$black;;
        "+red+") lineColor=$red;;
        #....
      esac
function GETCOLOR() {
    if [[ $1 =~ \+[a-Z]+\+? ]]
    then
        local match="${BASH_REMATCH[0]}"
        case "$match" in
            +black+|+red+|+green+|+blue+|+purple+|+cyan+|+yellow+|+white+)
                match="${match//+}"
                lineColor="${!match}"
                ;;
            *)
                lineColor="$reset"
                ;;
        esac
    fi
}
function GETCOLOR() {
    if [[ $1 =~ \+([a-Z]+)\+? ]]
    then
        local match="${BASH_REMATCH[1]}"
        case "$match" in
            black|red|green|blue|purple|cyan|yellow|white)
                lineColor="${!match}"
                ;;
            *)
                lineColor="$reset"
                ;;
        esac
    fi
}

Context

StackExchange Code Review Q#158149, answer score: 2

Revisions (0)

No revisions yet.