Comment vérifier si un fichier est un lien symbolique vers un répertoire?

64

Je peux vérifier si un fichier existe et est un lien symbolique avec -L

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

et si c'est un répertoire avec -d:

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

Mais comment puis-je tester uniquement les liens vers des répertoires?


J'ai simulé tous les cas dans un dossier de test:

/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
la source

Réponses:

75

Il suffit de combiner les deux tests avec &&:

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

la source
1
Si vous voulez vérifier les fichiers cachés et les répertoires aussi, faites-le avant:shopt -s dotglob
rubo77
2
[-L "$ file"] && [-d "$ file"] n'est-il pas meilleur? Quelque chose avec la portabilité entre les coquilles iirc.
Lennart Rolland
3
L'exemple de code utilisé par @Lennart OP est utilisé [[comme point de départ logique. Une discussion sur les mérites de [vs [[est hors de portée pour cette réponse (mais disponible ici ).
1

Une solution avec findet en utilisant une fonction:

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
la source
Utiliser findet while readpour ça, c'est un peu exagéré ...
Camilo Martin
1
Find est vraiment utile si vous ne recherchez que certains fichiers
rubo77