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.
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 <http://www.gnu.org/licenses/>.
"
help="
Usage: ./sopman.sh [--help|--version]
[options]
--search Search sopman archive for a string. '--search <search string>'
--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}================================================================[sopman]====${reset}")"
footer="$(echo -e "${cyan}============================================================================${reset}")"
#Functions
function search() {
echo -e "${green}Search results for \"$searchString\":${reset}\n"
grep -rnw sops/ -e "$searchString" --include "*.sopman.txt"
}
function motd() {
clear
echo "$header"
while read -r line; do
GETCOLOR "$line"
newLine=$(echo "$line" | sed "s/+[a-Z]\++//g")
# shopt -s extglob
# new_line=${line//(\+)}
echo -e "${lineColor}${newLine}${reset}"
done <"motd"
echo "$footer"
}
function menu0 {
fcount="0"
clear
echo "$header"
motd
echo -e "${green}0] Search ${reset}"
for sop in "${sops[@]}"
do
let fcount=fcount+1
echo -e "${green}$fcount) ${sop:5:-11} ${reset}"
done
echo "$footer"
}
function GETCOLOR() {
if [[ 1ドル =~ \+[a-Z]+\+? ]]; then
local match=${BASH_REMATCH[0]};
case $match in
"+black+") lineColor=$black;;
"+red+") lineColor=$red;;
"+green+") lineColor=$green;;
"+blue+") lineColor=$blue;;
"+purple+") lineColor=$purple;;
"+cyan+") lineColor=$cyan;;
"+yellow+") lineColor=$yellow;;
"+white+") lineColor=$white;;
*) lineColor=$reset;;
esac
fi
}
for ((arg=0;arg<"${#args[@]}";arg++)); do
[ "${args[$arg]}" == "--version" ] && echo "${version}" && exit
[ "${args[$arg]}" == "--help" ] && echo "${help}" && exit
[ "${args[$arg]}" == "--license" ] && echo "${license}" && exit
[ "${args[$arg]}" == "--search" ] && searchString=${args[$arg+1]} && clear && echo "$header" && search && echo "$footer" && exit
[ "${args[$arg]}" == "--motd" ] && clear && echo "$header" && motd && exit
#[ "${args[$arg]}" == "--" ] && echo ${args[$arg]}
done
while [ $endscript = "false" ]
do
menu0
while [ $stoploop = "false" ]
do
printf "Enter your selection (q to quit) : "
read -r input1
if [ "$input1" = "q" ]; then
echo -e "${cyan}Bye-Bye${reset}"
exit
fi
if [ "$input1" -eq "0" ]; then
printf "Search for: "
read -r searchString
clear
echo "$header"
search
echo "$footer"
printf "[ 'm' to return to menu, anything else to quit ] : "
read -r input3
if [ "$input3" = "m" ]; then
break
else
echo -e "${cyan}Bye-Bye${reset}"
exit
fi
fi
if [ "$input1" -ge "1" ] && [ "$input1" -le "$length" ]; then
clear
echo "$header"
while read -r line; do
GETCOLOR "$line"
newLine=$(echo "$line" | sed "s/+[a-Z]\++//g")
echo -e "${lineColor}${newLine}${reset}"
done <"${sops[$input1-1]}"
echo "$footer"
printf "[ 'm' to return to menu, anything else to quit ] : "
read -r input2
if [ "$input2" = "m" ]; then
break
else
echo -e "${cyan}Bye-Bye${reset}"
exit
fi
else
echo -e "${red}ERROR! Please select an option : ${reset}"
retryCount=$((retryCount+1))
if [ "$retryCount" -ge "3" ]; then
echo -e "${red}EXIT!${reset}"
exit
fi
fi
done
done
-
\$\begingroup\$ What are you looking for from the code review? \$\endgroup\$chicks– chicks2017年03月18日 22:32:56 +00:00Commented Mar 18, 2017 at 22:32
-
\$\begingroup\$ It would be great to have an answer to the Find and Replace Question . Also looking for corrections, optimizations & general improvements or suggestions. \$\endgroup\$Matt– Matt2017年03月19日 00:09:30 +00:00Commented Mar 19, 2017 at 0:09
1 Answer 1
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
}
-
\$\begingroup\$ Excellent response. I updated the Github Project per your suggestions. \$\endgroup\$Matt– Matt2017年03月22日 05:24:59 +00:00Commented Mar 22, 2017 at 5:24
-
\$\begingroup\$ I followed your link - there's a few more places where
echo -e
is still used, but the-e
is no longer needed. And"($echo -e something)"
can simplify to"something"
forheader
andfooter
. \$\endgroup\$Toby Speight– Toby Speight2017年03月22日 08:47:21 +00:00Commented Mar 22, 2017 at 8:47