#!/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;