Como verifico se um arquivo é um link simbólico para um diretório?

64

Posso verificar se existe um arquivo e é um link simbólico com -L

for file in *; do
    if [[ -L "$file" ]]; then echo "$file is a symlink"; else echo "$file is not a symlink"; fi
done

e se for um diretório com -d:

for file in *; do
    if [[ -d "$file" ]]; then echo "$file is a directory"; else echo "$file is a regular file"; fi
done

Mas como posso testar apenas links para diretórios?


Simulei todos os casos em uma pasta de teste:

/tmp/test# ls
a  b  c/  d@  e@  f@

/tmp/test# file *
a: ASCII text
b: ASCII text
c: directory
d: symbolic link to `c'
e: symbolic link to `a'
f: broken symbolic link to `nofile'
rubo77
fonte

Respostas:

75

Basta combinar os dois testes com &&:

if [[ -L "$file" && -d "$file" ]]
then
    echo "$file is a symlink to a directory"
fi

fonte
11
Se você quiser verificar arquivos e diretórios ocultos também preceder isso antes:shopt -s dotglob
rubo77
2
[-L "$ file"] e& [-d "$ file"] não são melhores? Algo com portabilidade entre conchas iirc.
Lennart Rolland #
3
O código de exemplo do @Lennart OP usa [[, e tomei isso como ponto de partida lógico. Uma discussão sobre o mérito de [vs [[está fora do escopo desta resposta (mas disponível aqui ).
1

Uma solução com finde usando uma função:

dosomething () {
    echo "doing something with $1"; 
}
find -L -path './*' -prune -type d| while read file; do 
    if [[ -L "$file" && -d "$file" ]];
        then dosomething "$file";
    fi; 
done
rubo77
fonte
Usando finde while readpara isso é um bocado exagero ...
Camilo Martin
11
Encontrar é realmente útil se você busca apenas para determinados arquivos
rubo77