Não consigo pensar em nenhum truque ou utilitário de expansão para fazer tudo de uma vez. Então, um loop é o caminho a percorrer. Aqui está um código que funciona tanto no bash quanto no zsh e acomoda diretórios com nomes arbitrários.
## Usage: set_directory_chain VAR FILENAME
## Set VAR to the chain of directories leading to FILENAME
## e.g. set_directory_chain a /usr/bin/env is equivalent to
## a=(/ /usr /usr/bin /usr/bin/env)
set_directory_chain () {
local __set_directory_chain_a __set_directory_chain_path
__set_directory_chain_a=()
__set_directory_chain_path=$2
while [[ __set_directory_chain_path = *//* ]]; do
__set_directory_chain_path=${__set_directory_chain_path//\/\///}
done
if [[ $__set_directory_chain_path != /* ]]; then
__set_directory_chain_path=$PWD/$__set_directory_chain_path
fi
while [[ -n $__set_directory_chain_path ]]; do
__set_directory_chain_a=("$__set_directory_chain_path" "${__set_directory_chain_a[@]}")
__set_directory_chain_path=${__set_directory_chain_path%/*}
done
eval "$1=(/ \"\${__set_directory_chain_a[@]}\")"
}
## Apply a command to all the directories in a chain
## e.g. apply_on_directory_chain /usr/bin/env ls -ld is equivalent to
## ls -ld / /usr /usr/bin /usr/bin/env
apply_on_directory_chain () {
local __apply_on_directory_chain_a
set_directory_chain __apply_on_directory_chain_a "$1"
shift
"$@" "${__apply_on_directory_chain_a[@]}"
}
lschain () {
for x; do apply_on_directory_chain "$x" ls -ld; done
}
Observe que, se isso tratar a cadeia de diretórios como uma string. Se houver ..
componentes ou links simbólicos, isso pode não ser o que você precisa. Por exemplo, se você quiser verificar as permissões nos diretórios, precisará resolver o diretório para um caminho absoluto primeiro. Em zsh, você pode usar /path/to/foo(:A)
. No Linux, você pode usar readlink -f /path/to/foo
.