#!/usr/bin/env bash # each-site.sh — run a command for each site under $HCIROOT. # Replaces v1 `each_site` / `each_site_hdr` / `each_site_tcl` patterns. # # Usage: # each-site.sh [--hciroot DIR] [--hdr] [--filter REGEX] # # The current site is exposed to CMD as the env vars HCISITE and HCISITEDIR. # The literal token {} in CMD, if present, is replaced with the site name. # # Examples: # each-site.sh 'lib/nc-find.sh --name adt --netconfigs "$HCISITEDIR/NetConfig"' # each-site.sh --hdr 'echo "Hey from $HCISITE; netconfig=$HCISITEDIR/NetConfig"' # each-site.sh --filter '^(ancout|epic)$' 'wc -l "$HCISITEDIR/NetConfig"' # each-site.sh 'lib/nc-parse.sh list-protocols "$HCISITEDIR/NetConfig" | wc -l' # # --hdr prints a "===== =====" header before each run. set -o pipefail HCIROOT_OVR="" HEADER=0 FILTER="" while [ $# -gt 0 ]; do case "$1" in --hciroot) shift; HCIROOT_OVR="$1" ;; --hdr) HEADER=1 ;; --filter) shift; FILTER="$1" ;; -h|--help) sed -n '2,18p' "$0"; exit 0 ;; --) shift; break ;; -*) echo "each-site: unknown flag: $1" >&2; exit 2 ;; *) break ;; esac shift done [ $# -ge 1 ] || { echo "each-site: needs a CMD" >&2; exit 2; } CMD="$*" ROOT="${HCIROOT_OVR:-${HCIROOT:-}}" [ -n "$ROOT" ] && [ -d "$ROOT" ] || { echo "each-site: no \$HCIROOT (or --hciroot)" >&2; exit 2; } # Site = subdir of ROOT that contains a NetConfig file. SITES=$(find "$ROOT" -mindepth 1 -maxdepth 2 -name NetConfig -type f 2>/dev/null \ | xargs -I{} dirname {} 2>/dev/null \ | xargs -I{} basename {} 2>/dev/null \ | sort -u) [ -n "$SITES" ] || { echo "each-site: no sites with NetConfig under $ROOT" >&2; exit 1; } while IFS= read -r site; do [ -z "$site" ] && continue if [ -n "$FILTER" ] && ! printf '%s' "$site" | grep -Eq -- "$FILTER"; then continue; fi [ "$HEADER" = "1" ] && printf '\n===== %s =====\n' "$site" HCISITE="$site" HCISITEDIR="$ROOT/$site" eval "${CMD//\{\}/$site}" done <<< "$SITES"