#!/bin/bash # BASEDIR=`pwd` # More safety, by turning some bugs into errors. # Without `errexit` you don’t need ! and can replace # PIPESTATUS with a simple $?, but I don’t do that. set -o errexit -o pipefail -o noclobber -o nounset # -allow a command to fail with !’s side effect on errexit # -use return value from ${PIPESTATUS[0]}, because ! hosed $? ! getopt --test > /dev/null if [[ ${PIPESTATUS[0]} -ne 4 ]]; then echo 'I’m sorry, `getopt --test` failed in this environment.' exit 1 fi OPTIONS=phe: LONGOPTS=print-subdir,help,exclude: # -regarding ! and PIPESTATUS see above # -temporarily store output to be able to check for errors # -activate quoting/enhanced mode (e.g. by writing out “--options”) # -pass arguments only via -- "$@" to separate them correctly ! PARSED=$(getopt --options=$OPTIONS --longoptions=$LONGOPTS --name "$0" -- "$@") if [[ ${PIPESTATUS[0]} -ne 0 ]]; then # e.g. return value is 1 # then getopt has complained about wrong arguments to stdout exit 2 fi # read getopt’s output this way to handle the quoting right: eval set -- "$PARSED" p=n exc="" # now enjoy the options in order and nicely split until we see -- while true; do case "$1" in -p|--print-subdir) p=y shift ;; -h|--help) echo -e "NAME\n\tineach - executes a command in each subdirectory" echo -e "SYNOPSIS\n\tineach [-p, --print-subdir] [-e, --exclude dir1,dir2,...,dirn] \"command\"" exit 0 shift ;; -e|--exclude) exc="$2" shift 2 ;; --) shift break ;; *) echo "Programming error" exit 3 ;; esac done # handle non-option arguments if [[ $# -ne 1 ]]; then echo "$0: A single command is required." exit 4 fi for subdir in `find $BASEDIR -maxdepth 1 -type d` do bn=`basename $subdir` if [[ $subdir != $BASEDIR ]] && [[ ",$exc," != *",$bn,"* ]]; then cd $subdir if [[ $p = "y" ]]; then echo -en "\n\n\033[1;33m╔" for ((i=1;i<=$((${#bn} + 2));i++)); do echo -n "═"; done ; echo "╗" echo "║ $bn ║" echo -n "╚" for ((i=1;i<=$((${#bn} + 2));i++)); do echo -n "═"; done ; echo "╝" echo -e "\033[00m" fi eval $1 fi done