Commit | Line | Data |
---|---|---|
1d73b96f SBS |
1 | #!/usr/bin/env bash |
2 | # Desc: Applies chmod to a segment of a directory branch of the | |
3 | # filesystem tree. Changes applied to all directories starting with | |
4 | # TIP and ending with (but not including) TRUNK. | |
5 | ||
6 | # Usage: chmoddirbr [path TRUNK] [path TIP] | |
7 | # Input: arg1: TRUNK path | |
8 | # arg2: TIP path | |
9 | # arg3+ arguments to be passed on to chmod | |
10 | # Output: None. | |
11 | # Depends: GNU Coreutils 8.30 (chmod), Bash 5.0.3 | |
12 | ||
13 | # Example: chmoddirbr /tmp /tmp/1/2/3/4/5/6 o+rx | |
14 | # This runs `chmod o+rx /tmp/1/2/3/4/5/6` | |
15 | # `chmod o+rx /tmp/1/2/3/4/5` | |
16 | # `chmod o+rx /tmp/1/2/3/4` | |
17 | # ... | |
18 | # `chmod o+rx /tmp/1` | |
19 | ||
20 | yell() { echo "$0: $*" >&2; } # print script path and all args to stderr | |
21 | die() { yell "$*"; exit 111; } # same as yell() but non-zero exit status | |
22 | try() { "$@" || die "cannot $*"; } # runs args as command, reports args if command fails | |
23 | main() { | |
24 | declare -a chmod_args | |
25 | declare -a dirs_branch | |
26 | ||
27 | arg1="$1"; shift; | |
28 | arg2="$1"; shift; | |
29 | chmod_args=("$@"); | |
30 | ||
31 | #yell "DEBUG:arg1:$arg1"; | |
32 | #yell "DEBUG:arg2:$arg2"; | |
33 | #yell "DEBUG:chmod_args:${chmod_args[@]}"; | |
34 | ||
35 | # Check input dirs | |
36 | if [[ -d $arg1 ]]; then | |
37 | dir_trunk="$(readlink -f "$arg1")"; # use full path | |
38 | #yell "DEBUG:dir_trunk:$dir_trunk"; | |
39 | else | |
40 | die "ERROR:TRUNK is not a dir:$arg1"; | |
41 | fi; | |
42 | if [[ -d $arg2 ]]; then | |
43 | dir_tip="$(readlink -f "$arg2")"; # use full path | |
44 | #yell "DEBUG:dir_tip :$dir_tip"; | |
45 | else | |
46 | die "ERROR:TIP is not a dir:$arg2"; | |
47 | fi; | |
48 | ||
49 | # Check if $dir_trunk points to $dir_tip | |
50 | if [[ $dir_tip =~ ^"$dir_trunk" ]]; then | |
51 | : | |
52 | #yell "DEBUG:Tip is within trunk."; | |
53 | else | |
54 | yell "NOTE:dir_trunk:$dir_trunk"; | |
55 | yell "NOTE:dir_tip :$dir_tip"; | |
56 | die "ERROR:Tip is not within trunk."; | |
57 | fi; | |
58 | ||
59 | # Assemble dirs_branch array | |
60 | ## Note: dirs_branch will not include $dir_trunk | |
61 | point="$dir_tip"; | |
62 | while [[ $point != $dir_trunk ]]; do | |
63 | #yell "DEBUG:start point :$point"; | |
64 | #yell "DEBUG:start dir_trunk:$dir_trunk"; | |
65 | dirs_branch+=("$point"); | |
66 | ||
67 | # Walk up branch | |
68 | point="$(dirname "$point")"; | |
69 | #yell "DEBUG:end point :$point"; | |
70 | #yell "DEBUG:end dir_trunk:$dir_trunk"; | |
71 | #yell ""; # debug | |
72 | done; | |
73 | unset point; | |
74 | #yell "DEBUG:${dirs_branch[@]}"; | |
75 | ||
76 | # Perform action | |
77 | n=0; | |
78 | for dir in "${dirs_branch[@]}"; do | |
79 | yell "STATUS:$((n+1)):Running: chmod $chmod_args $dir"; | |
80 | try chmod "$chmod_args" "$dir" && ((n++)); | |
81 | done; | |
82 | yell "STATUS:Finished. Ran chmod $((n)) times."; | |
83 | } # main program | |
84 | ||
85 | main "$@"; | |
86 | ||
87 | # Author: Steven Baltakatei Sandoval | |
88 | # License: GPLv3+ |