feat(user/chmoddirbr):Add script to perform chmod on dir branch
authorSteven Baltakatei Sandoval <baltakatei@gmail.com>
Wed, 19 Jan 2022 21:23:23 +0000 (21:23 +0000)
committerSteven Baltakatei Sandoval <baltakatei@gmail.com>
Wed, 19 Jan 2022 21:23:23 +0000 (21:23 +0000)
user/chmoddirbr [new file with mode: 0644]

diff --git a/user/chmoddirbr b/user/chmoddirbr
new file mode 100644 (file)
index 0000000..6959c13
--- /dev/null
@@ -0,0 +1,88 @@
+#!/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+