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
-e
em vez de-f
, pois queremos garantir que os arquivos existam. A opção-v
fornece 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 porreadlink
comvar=${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/xx
tenham 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
)