| 1 | #!/usr/bin/env bash |
| 2 | # Desc: Provides newline-delimited list of each parent dir |
| 3 | |
| 4 | yell() { echo "$0: $*" >&2; } # print script path and all args to stderr |
| 5 | die() { yell "$*"; exit 111; } # same as yell() but non-zero exit status |
| 6 | try() { "$@" || die "cannot $*"; } # runs args as command, reports args if command fails |
| 7 | get_parent_dirnames() { |
| 8 | # Desc: Provides newline-delimited list of each parent dir of a file or dir |
| 9 | # Usage: get_parent_dirnames arg1 |
| 10 | # Input: arg1 input path |
| 11 | # Output: stdout newline-delimited list of parent dirs |
| 12 | # Version: 0.0.1 |
| 13 | # Depends: yell(), die(), try() |
| 14 | local path |
| 15 | |
| 16 | # Check input |
| 17 | if [[ $# -ne 1 ]]; then die "FATAL:Incorrect number of arguments:$#"; fi; |
| 18 | if ! { [[ -f $1 ]] || [[ -d $1 ]]; }; then die "FATAL:Not a file or dir:$1"; fi; |
| 19 | |
| 20 | # Process path |
| 21 | path="$1"; |
| 22 | while [[ -f $path ]] || [[ -d $path ]]; do |
| 23 | path="$(dirname "$path")"; |
| 24 | name_base_previous="$name_base"; |
| 25 | name_base="$(basename "$path")"; |
| 26 | ## Check for stop condition (dirname returns same result as previous iteration) |
| 27 | if [[ $name_base == "$name_base_previous" ]]; then break; fi; |
| 28 | echo "$name_base"; |
| 29 | done; |
| 30 | }; # Output parent dirnames to stdout |
| 31 | |
| 32 | # Test code |
| 33 | sleep 1 && get_parent_dirnames /home/baltakatei/Downloads/ & # should work |
| 34 | sleep 2 && get_parent_dirnames /home/baltakatei/Downloads/ foo & # should fail |
| 35 | sleep 3 && get_parent_dirnames bar/baz & # should fail |
| 36 | sleep 4; |