I'm writing a helper script that I wish to be able to share with my co-workers. We all work using macOS Mojave, but all have their own shell configurations. For example, I actually use ZSH and bash 5.0.
There are often times where I am working with data that is output from our nightly testing that runs on a remote cluster.
I could just run the tests locally, but that would take up most of my day. So I wrote a script that fetches the data from the remote server.
Recently, a few coworkers have expressed interest in using this script. So I was hoping to get a quick review of it, before I sent it off to them.
My goal is to have a reliable, well-written script that could be easy to debug for my coworkers. Also it being able to work on any macOS would be awesome.
#!/usr/bin/env bash
NORMAL='\033[0m'
RED='\033[1;31m'
GREEN='\033[0;32m'
BLUE='\033[1;34m'
MAGENTA='\033[1;4;35m'
YELLOW='\033[1;33m'
dry_run=0
lookback=1
folder=""
BISON=${BISON_DIR:-$HOME/Documents/projects/bison}
function foldernames () {
(printf "Calvert_Cliffs-1_PROTOTYPE IFA_636 RIA_CABRI_REP_Na4\n"
printf "FUMEXII_Regate IFA_677 RIA_NSRR_FK\n"
printf "HBEP LOCA_ANL_cladding_burst_tests Riso_AN2\n"
printf "HbepR1 LOCA_Hardy_cladding_test Riso_AN3\n"
printf "IFA_431 LOCA_IFA_650 Riso_AN4\n"
printf "IFA_432 LOCA_MT4_MT6A Riso_AN8\n"
printf "IFA_513 LOCA_ORNL_cladding_burst_tests Riso_GE7_ZX115\n"
printf "IFA_515_RodA1 LOCA_PUZRY_cladding_burst_tests Riso_GEm_STR013\n"
printf "IFA_519 LOCA_REBEKA_cladding_burst_tests Riso_II3\n"
printf "IFA_534 OSIRIS_H09 Riso_II5\n"
printf "IFA_535 OSIRIS_J12 Super_Ramp\n"
printf "IFA_562 RE_Ginna_Rodlets Tribulation\n"
printf "IFA_597_3 RIA_CABRI_REP_Na US_PWR_16_x_16\n") | column -t
}
function usage () {
printf "Usage: bisfetch [-n] [-l num] [-f folder] [folder(s) ...]\n"
printf " -h \t - show this message\n"
printf " -n \t - perform a dry-run\n"
printf " -l \t - Integer value; Look back a previous run; Defaults to 1 (most-recent)\n"
printf " -f \t - Folder of interest; The flag is optional but a folder is required."
printf "\n"
printf "Folder of interest required! Possible folder names include:\n\n"
foldernames
exit 1
}
while getopts ":hnl:f:" flag; do
case "$flag" in
n ) dry_run=1
;;
l ) lookback=${OPTARG}
;;
h ) usage
;;
f ) folder="${OPTARG}"
;;
: ) echo "Invalid options: $OPTARG requires an argurment" 1>&2
exit 1
;;
\? ) echo "Usage: bisfetch [-n] [-l num] [-f folder] [folder(s) ...]"
exit 1
;;
esac
done
shift $((OPTIND-1))
# Check to ensure folder is specified
if [ -z "$folder" ] && [ -z "$1" ]; then
printf "%b\n\n" "${RED}You must specify a folder of interest:${NORMAL}"
foldernames
exit 1
fi
# If no -f flag then assign folder to first ARG
[ -n "$1" ] && folder="$1"
# Find all *_out.csv files on Falcon1 for specific folder
# This is some bash-fu, but bassically we want to find the most recently
# modified folder of the type 'bison_XXXXXXXX'
# We then want to find all the *_out.csv files inside the folder specified at the
# command-line within the 'bison_XXXXXXXX' folder.
mapfile -t files < <(ssh falcon1 -qn 'newest=$(find /projects/bison/git/* -mindepth 0 -maxdepth 0 -type d -regex ".*/bison_[0-9]+" -printf "%T@\t%f\n" | ' \
'sort -t\t -r -nk1,5 | ' \
'sed -n '"$lookback"'p | ' \
'cut -f2-); ' \
'find /projects/bison/git/$newest/assessment/LWR/validation/'"$folder"'/* -type f -name "*_out.csv" -not -path "*/doc/*" -printf "%p\n" 2>/dev/null')
# Modify remote paths to fit for local paths
mapfile -t local_paths < <(for i in "${files[@]}"; do
echo "$i" |
sed -E "s|/projects/bison/git/bison_[0-9]{8}|$BISON|g"; done)
# If ssh returned no results then error out.
if [[ -z "${files[0]}" ]]; then
printf "%b\n\n" "${RED}ERROR: Folder '$folder' Not Found!${NORMAL}"
printf "%b\n" "${YELLOW}Possible Folder Names Include:${NORMAL}"
foldernames
exit 1
else
printf "\n\t📁 Inspecting Nightly Folder %b for Assessment %b:\n" \
"${MAGENTA}${files[0]:20:14}${NORMAL}" "${MAGENTA}$folder${NORMAL}"
fi
for ((i=0; i<${#files[@]}; i++)); do
if [[ $dry_run == 0 ]]; then
printf "\t╭─ %b %s\n" "${BLUE}Remote =>${NORMAL}" "${files[i]}"
printf "\t├─ %b %s\n" "${YELLOW}Local =>${NORMAL}" "${local_paths[i]}"
printf "\t╰─ Fetching Remote File...\r"
if scp -qp falcon1:"${files[i]}" "${local_paths[i]}" 2>/dev/null; then
printf "\t%b\n\n" "╰─ Fetching Remote File… ${GREEN}Successful!${NORMAL}"
else
printf "\t%b\n\n" "╰─ Fetching Remote File… ${RED}Error!{$NORMAL}"
fi
else
printf "\t╭─ %b %s\n" "${BLUE}Remote =>${NORMAL}" "${files[i]}"
printf "\t╰─ %b %s\n\n" "${YELLOW}Local =>${NORMAL}" "${local_paths[i]}"
fi
done
```