+#!/usr/bin/env bash
+# Desc: Provides newline-delimited list of each parent dir
+
+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
+get_parent_dirnames() {
+ # Desc: Provides newline-delimited list of each parent dir of a file or dir
+ # Usage: get_parent_dirnames arg1
+ # Input: arg1 input path
+ # Output: stdout newline-delimited list of parent dirs
+ # Version: 0.0.1
+ # Depends: yell(), die(), try()
+ local path
+
+ # Check input
+ if [[ $# -ne 1 ]]; then die "FATAL:Incorrect number of arguments:$#"; fi;
+ if ! { [[ -f $1 ]] || [[ -d $1 ]]; }; then die "FATAL:Not a file or dir:$1"; fi;
+
+ # Process path
+ path="$1";
+ while [[ -f $path ]] || [[ -d $path ]]; do
+ path="$(dirname "$path")";
+ name_base_previous="$name_base";
+ name_base="$(basename "$path")";
+ ## Check for stop condition (dirname returns same result as previous iteration)
+ if [[ $name_base == "$name_base_previous" ]]; then break; fi;
+ echo "$name_base";
+ done;
+}; # Output parent dirnames to stdout
+
+# Test code
+sleep 1 && get_parent_dirnames /home/baltakatei/Downloads/ & # should work
+sleep 2 && get_parent_dirnames /home/baltakatei/Downloads/ foo & # should fail
+sleep 3 && get_parent_dirnames bar/baz & # should fail
+sleep 4;