Comment puis-je faire pour trouver la plupart des liens symboliques, mais pas tous?

10

Mon système d'exploitation et mon répertoire personnel se trouvent sur un SSD. Je stocke des fichiers volumineux sur un disque dur et un lien symbolique de mon répertoire personnel vers le disque dur (par exemple, ~ / Videos / Films est un lien symbolique vers / mnt / hdd / Films). J'ai également un certain nombre de préfixes Wine, dont chacun a dosdevices / z: un lien symbolique vers /.

Donc, si j'ai utilisé find sans -L, il manquera tout ce qui se trouve sur le disque dur. Mais si j'utilise find avec -L, il se retrouve dans une boucle en raison du lien symbolique de Wine vers /.

Existe-t-il un moyen judicieux de résoudre ce problème, afin de trouver les recherches là où je le souhaite? Intuitivement, je veux quelque chose dans le sens de "suivre les liens symboliques, sauf s'ils se trouvent dans un répertoire appelé dosdevices". "Suivre les liens symboliques vers un élément du disque dur" fonctionnerait également.

Mark Raymond
la source

Réponses:

11

Le -pruneprimaire dit de findne pas récurser sous un répertoire.

find -L -path ~/.wine/dosdevices -prune -o -type f -name 'My Favorite Movie.*' -print

Si vous souhaitez utiliser -lnamedans votre condition, vous ne pouvez pas utiliser l' -Loption, car la -Lplupart des prédicats agissent sur la cible du lien, y compris -lname. Ma recommandation dans ce cas serait d'utiliser à la fois votre répertoire personnel et la racine du disque dur comme racines de votre recherche.

find ~ /mnt/hdd -xtype f -name 'My Favorite Movie.*'

Vous pouvez exécuter find ~ -type l …pour rassembler une liste de liens symboliques et les utiliser comme racines supplémentaires.

( IFS=$'\n'; set -f;
  find ~ $(find ~ -type l -lname '/mnt/hdd/*') \
       -xtype f -name 'My Favorite Movie.*' )

Si vous voulez vraiment récapituler sous des liens symboliques, vous pouvez exclure des liens symboliques spécifiques par cible plutôt que par nom. Cependant, vous ne pouvez exclure qu'une liste finie, pas un modèle ou un sous-arbre de cette façon.

find -L \( -samefile /exclude/this -o -samefile ~/and/that \) -prune -o \
     -type f -name 'My Favorite Movie.*' -print

Vous pouvez utiliser d'autres critères tels que ! -writable(les fichiers pour lesquels vous n'avez pas la permission d'écrire), mais je ne pense pas que GNU find ait un moyen de récurser sous des liens symboliques uniquement si leur texte cible correspond à une certaine expression.

Vous pouvez créer une findcommande qui fait presque ce que vous voulez, sauf pour ne pas exclure suffisamment de liens symboliques, exécuter find2perl pour convertir la requête en script Perl et modifier un peu le script Perl. Cependant, il existe de nombreux commutateurs de GNU que find2perl ne reconnaît pas.

Gilles 'SO- arrête d'être méchant'
la source
Merci! -pruneest juste le genre de chose que je cherchais. J'ai trouvé que la find ~ \( -lname ~ -o -lname ~/\* -o -lname / \) -xtype dliste de tous les liens symboliques que je ne veux pas suivre; J'essaie maintenant de trouver un moyen d'utiliser cette requête pour tailler.
Mark Raymond
@MarkRaymond Le principe général est find ~ <negative criteria> -prune -o <positive criteria> -print, alorsfind ~ \( -lname ~ -o -lname ~/\* -o -lname / \) -xtype d -prune -o <whatever it is you want> -print
Gilles 'SO- arrête d'être méchant'
@Giles - cela fonctionne très bien sans -L, mais une fois que j'ajoute -L, les expressions -lname ne fonctionnent plus (comme le dit la page de manuel, elles ne fonctionneront plus). Donc, fondamentalement, j'ai ensuite besoin de certaines conditions pour suivre les liens symboliques et d'autres pas!
Mark Raymond
Je ne peux pas penser à un moyen de faire exactement ce que vous voulez trouver. Voir mon montage pour quelques approximations.
Gilles 'SO- arrête d'être méchant'
1

Pour rechercher TOUS les liens, cela a fonctionné pour moi:

find -L . -name \*.txt
Jim
la source
0

Combien de liens symboliques vers des disques durs avez-vous? Si ce n'est pas trop, une solution consiste à ne pas utiliser "-L" tout en spécifiant explicitement les liens symboliques que vous souhaitez suivre sur la ligne de commande find. Quelque chose comme:

find .  ~/Videos/Films -name '*file I want*' ...

Ceci recherchera le répertoire courant (".") Ainsi que le lien symbolique "~ / Videos / Films" mais ne descendra pas dans d'autres liens symboliques.

John1024
la source
0

Une autre solution qui contourne le problème (au moins pour mon cas) consiste à utiliser des montures de liaison au lieu de liens symboliques pour les répertoires sur le disque dur. Cela se fait en ajoutant des entrées /etc/fstabcomme ceci:

/mnt/hdd/Films /home/mark/Videos/Films none bind 0 0

Mark Raymond
la source