#!/usr/bin/env bash # Desc: Applies chmod to a segment of a directory branch of the # filesystem tree. Changes applied to all directories starting with # TIP and ending with (but not including) TRUNK. # Usage: chmoddirbr [path TRUNK] [path TIP] # Input: arg1: TRUNK path # arg2: TIP path # arg3+ arguments to be passed on to chmod # Output: None. # Depends: GNU Coreutils 8.30 (chmod), Bash 5.0.3 # Example: chmoddirbr /tmp /tmp/1/2/3/4/5/6 o+rx # This runs `chmod o+rx /tmp/1/2/3/4/5/6` # `chmod o+rx /tmp/1/2/3/4/5` # `chmod o+rx /tmp/1/2/3/4` # ... # `chmod o+rx /tmp/1` yell() { echo "$0: $*" >&2; } # print script path and all args to stderr die() { yell "$*"; exit 111; } # same as yell() but non-zero exit status try() { "$@" || die "cannot $*"; } # runs args as command, reports args if command fails main() { declare -a chmod_args declare -a dirs_branch arg1="$1"; shift; arg2="$1"; shift; chmod_args=("$@"); #yell "DEBUG:arg1:$arg1"; #yell "DEBUG:arg2:$arg2"; #yell "DEBUG:chmod_args:${chmod_args[@]}"; # Check input dirs if [[ -d $arg1 ]]; then dir_trunk="$(readlink -f "$arg1")"; # use full path #yell "DEBUG:dir_trunk:$dir_trunk"; else die "ERROR:TRUNK is not a dir:$arg1"; fi; if [[ -d $arg2 ]]; then dir_tip="$(readlink -f "$arg2")"; # use full path #yell "DEBUG:dir_tip :$dir_tip"; else die "ERROR:TIP is not a dir:$arg2"; fi; # Check if $dir_trunk points to $dir_tip if [[ $dir_tip =~ ^"$dir_trunk" ]]; then : #yell "DEBUG:Tip is within trunk."; else yell "NOTE:dir_trunk:$dir_trunk"; yell "NOTE:dir_tip :$dir_tip"; die "ERROR:Tip is not within trunk."; fi; # Assemble dirs_branch array ## Note: dirs_branch will not include $dir_trunk point="$dir_tip"; while [[ $point != $dir_trunk ]]; do #yell "DEBUG:start point :$point"; #yell "DEBUG:start dir_trunk:$dir_trunk"; dirs_branch+=("$point"); # Walk up branch point="$(dirname "$point")"; #yell "DEBUG:end point :$point"; #yell "DEBUG:end dir_trunk:$dir_trunk"; #yell ""; # debug done; unset point; #yell "DEBUG:${dirs_branch[@]}"; # Perform action n=0; for dir in "${dirs_branch[@]}"; do yell "STATUS:$((n+1)):Running: chmod $chmod_args $dir"; try chmod "$chmod_args" "$dir" && ((n++)); done; yell "STATUS:Finished. Ran chmod $((n)) times."; } # main program main "$@"; # Author: Steven Baltakatei Sandoval # License: GPLv3+