Last active
July 23, 2026 08:56
-
-
Save pasdam/57fe4cdb3a28da591963c0baad31bc7d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Color codes for output | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| NC='\033[0m' # No Color | |
| print_usage() { | |
| SCRIPT_NAME=$(basename "$0") | |
| echo "Description" | |
| echo "" | |
| echo "Usage: $SCRIPT_NAME <path1> [path2 ...] -- <command>" | |
| echo "Example: $SCRIPT_NAME src/ lib/ -- npm test" | |
| echo "Parameters:" | |
| echo " -h, --help Show this help message" | |
| exit "$1" | |
| } | |
| if [ $# -lt 3 ]; then | |
| print_usage 1 | |
| fi | |
| COMMAND="" | |
| PARSING_PATHS=true | |
| PATHS=() | |
| for arg in "$@"; do | |
| if [ "$arg" = "--" ]; then | |
| PARSING_PATHS=false | |
| continue | |
| fi | |
| if [ "$PARSING_PATHS" = true ]; then | |
| PATHS+=("$arg") | |
| else | |
| if [ -z "$COMMAND" ]; then | |
| COMMAND="$arg" | |
| else | |
| COMMAND="$COMMAND $arg" | |
| fi | |
| fi | |
| done | |
| if [ ${#PATHS[@]} -eq 0 ]; then | |
| echo -e "${RED}Error: No paths specified${NC}" | |
| print_usage 2 | |
| fi | |
| if [ -z "$COMMAND" ]; then | |
| echo -e "${RED}Error: No command specified${NC}" | |
| print_usage 3 | |
| fi | |
| for path in "${PATHS[@]}"; do | |
| if [ ! -e "$path" ]; then | |
| echo -e "${RED}Error: Path does not exist: $path${NC}" | |
| exit 1 | |
| fi | |
| done | |
| log() { printf '%s %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$1"; } | |
| SNAP_BEFORE=$(mktemp) | |
| SNAP_AFTER=$(mktemp) | |
| cleanup() { | |
| rm -f "$SNAP_BEFORE" "$SNAP_AFTER" | |
| } | |
| trap printout SIGINT | |
| printout() { | |
| echo "" | |
| 1>&2 echo "Watch path terminated forcefully" | |
| cleanup | |
| exit | |
| } | |
| trap cleanup EXIT | |
| eval "${COMMAND}" | |
| while true | |
| do | |
| ls -lRT "${PATHS[@]}" > "$SNAP_BEFORE" 2>&1 | |
| # md5 collapses the listing to one line so it always fits watch's | |
| # visible screen — watch -g only compares what is drawn on screen | |
| watch -t -g "ls -lRT ${PATHS[*]} | md5" > /dev/null | |
| ls -lRT "${PATHS[@]}" > "$SNAP_AFTER" 2>&1 | |
| CHANGED=$(diff "$SNAP_BEFORE" "$SNAP_AFTER" \ | |
| | grep -E '^[<>] [-dl]' \ | |
| | sed -E 's/^[<>] [^ ]+ +[^ ]+ +[^ ]+ +[^ ]+ +[^ ]+ +[A-Za-z]{3} +[0-9]+ +[0-9:]+ +[0-9]{4} +//' \ | |
| | sort -u) | |
| if [ -n "$CHANGED" ]; then | |
| printf "\n===================\n" | |
| log "changed: $CHANGED" | |
| printf "\n-------------------\n" | |
| fi | |
| eval "${COMMAND}" | |
| done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment