2
\$\begingroup\$

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
```
\$\endgroup\$

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.