Dado um nome de caminho canônico, como o seu, isso funcionará:
set -f --; IFS=/
for p in $pathname
do [ -e "$*/$p" ] || break
set -- "$@" "$p"
done; printf %s\\n "$*"
Isso imprime através do último componente totalmente existente / acessível de $pathname
e coloca cada um deles separadamente na matriz arg. O primeiro componente inexistente não é impresso, mas é salvo em $p
.
Você pode abordá-lo de maneira oposta:
until cd -- "$path" && cd -
do case $path in
(*[!/]/*)
path="${path%/*}"
;; (*) ! break
esac
done 2>/dev/null && cd -
Isso retornará adequadamente ou diminuirá $path
conforme necessário. Ele se recusa a tentar alterar /
, mas, se for bem-sucedido, imprimirá seu diretório de trabalho atual e o diretório para o qual ele muda para stdout. Sua corrente $PWD
também será inserida $OLDPWD
.
access(2)
não é muito granular, então a solução geralmente envolve escrever algo para iterate e testar cada elemento do caminho, por sua vez ...