trova tutti i collegamenti simbolici in un albero di directory che punta all'esterno di quell'albero


8

Spingo frequentemente alberi di directory in altre posizioni o copio i tarball su altre macchine e vorrei avere un metodo per verificare se eventuali collegamenti simbolici in un albero di directory A puntano a posizioni esterne ad A poiché queste verranno interrotte nel mosso / copiato directory.

Risposte:


7

Volete un programma chiamato realpath, usato insieme a find.

Per esempio:

find . -type l -exec realpath {} \; | grep -v "^$(pwd)"

1
L'incantesimo fornito riporta solo la posizione di destinazione offensiva, non il collegamento simbolico che lo indica. Come tale ho rimosso la mia accettazione. Si prega di vedere la mia "risposta" di seguito: unix.stackexchange.com/a/308899/24044 e se sei soddisfatto (o miglioralo) eliminerò la mia "risposta" e accetterò di nuovo la tua domanda.
Marco Junius Bruto

2

Utilizzare bindfs per creare un'altra vista dell'albero delle directory.

mkdir /tmp/view
bindfs /some/directory /tmp/view

Quindi utilizzare l' utilità symlink (fornita da molte distribuzioni o compilarla dal sorgente ) per rilevare i collegamenti tra file system.

symlinks -r /tmp/view | sed -n 's/^\(absolute\|other_fs\): //p'

(Si noti che l'analisi dell'output presuppone che i collegamenti simbolici e le relative destinazioni non contengano newline, né i percorsi ai collegamenti simbolici contengano la sottostringa  -> .) La stessa utilità può anche convertire i collegamenti simbolici assoluti in relativi (ma si vorrebbe farlo da la posizione originale).


2

Con zsh:

cd -P -- "$dir"
for i (**/*(ND@)) [[ $i:A = $PWD/* ]] || [[ $i:A = $PWD ]] || print -r -- "$i => $i:A"

Ora, se la directory è /fooe hai /foo/barun link simbolico /foo/baz, è un link la cui destinazione è in / pippo, ma una volta spostato, il link verrà comunque interrotto, quindi potresti voler anche abbinare i link simbolici a percorsi assoluti.

Ma anche allora, un bar => ../foo/bazin /foosarebbe un problema (falso negativo), così sarebbe un a => bdove si btrova un link simbolico all'esterno dell'albero (falso positivo, a seconda di come lo si desidera guardare)


2

Ho dovuto modificare un po 'la risposta data da @bahamat per farlo funzionare.

La versione fornita riportava semplicemente la posizione assoluta offensiva ma non il collegamento simbolico che la indica.

Ecco cosa ho usato (sono sicuro che può essere migliorato):

for f in $(find . -type l ); do echo -n $(realpath $f) && echo -n "|" && echo $f ; done | grep -v "^$(pwd)" | cut -d \| -f 2 

Ho trovato questo lo script più utile: for f in $(find . -type l); do echo $(realpath -m -q $f) '<-' $f; done | grep-v "^$(pwd)"(in particolare -me -qche filtra i collegamenti interrotti e non esterni)
Adam Lindberg,

1

Coreutils GNU si dimostra realpath, che risolve i collegamenti simbolici. Con questo, potresti confrontare il target di ogni symlink con la directory di lavoro corrente con qualcosa del tipo:

#!/bin/bash

find . | while read filename
do
  if realpath $filename | grep -E "^$PWD" > /dev/null
  then
    echo 'this file is safe'
  else
    echo 'this file links externally'
  fi
done

Diversi problemi: no -type l, nessuna -ropzione per read, IFS non sanificato read, $filenamenon citato, $PWDtrattato come un'espressione regolare, percorsi con caratteri di nuova riga non considerati, /foobarverrebbero abbinati per $PWD== "/ pippo"
Stéphane Chazelas
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.