Eu não acho que haja tal utilidade. Com o GNU readlink , você poderia fazer algo como:
is_in() (
needle=$(readlink -ve -- "$1" && echo .) || exit
haystack=$(readlink -ve -- "$2" && echo .) || exit
needle=${needle%??} haystack=${haystack%??}
haystack=${haystack%/} needle=${needle%/}
case $needle in
("$haystack" | "$haystack"/*) true;;
(*) false;;
esac
)
Isso resolve os todos links simbólicos para terminar com um caminho absoluto canônico para agulha e palheiro.
Explicação
- Obtemos o caminho absoluto canônico da agulha e do palheiro . Usamos
-eem vez de-f, pois queremos garantir que os arquivos existam. A opção-vfornece uma mensagem de erro se os arquivos não puderem ser acessados. - Como sempre,
--deve ser usado para marcar o final das opções e aspas, já que não queremos chamar o operador split + glob aqui. - A substituição de comandos em shells parecidos com Bourne tem um erro na medida em que remove all o caractere de nova linha do final da saída de um comando, não apenas aquele adicionado pelos comandos para terminar a última linha. O que isso significa é que, para um arquivo como
/foo<LF><LF>,$(readlink -ve -- "$1")retornaria/foo. A solução comum para isso é acrescentar um caractere não-LF (aqui.) e remover o caractere LF extra adicionado porreadlinkcomvar=${var%??}(remover os dois últimos caracteres). -
A agulha é considerada como estando no palheiro se é o palheiro ou se é palheiro / alguma coisa. No entanto, isso não funcionaria se o palheiro fosse
/(/etc, em vez disso, não é//something)./geralmente precisa ser tratado especialmente porque, embora/e/xxtenham o mesmo número de barras, um é um nível acima do outro.Uma maneira de resolver isso é substituir
/pela string vazia que é feita comvar=${var%/}(o único caminho que termina com/quereadlink -eé/, removendo, assim, um/à direita está mudando/para a string vazia).
Para a canonização dos caminhos de arquivos, você pode usar uma função auxiliar.
canonicalize_path() {
# canonicalize paths stored in supplied variables. '/' is returned as
# the empty string.
for _var do
eval '
'"$_var"'=$(readlink -ve -- "${'"$_var"'}" && echo .) &&
'"$_var"'=${'"$_var"'%??} &&
'"$_var"'=${'"$_var"'%/}' || return
done
}
is_in() (
needle=$1 haystack=$2
canonicalize_path needle haystack || exit
case $needle in
("$haystack" | "$haystack"/*) true;;
(*) false;;
esac
)