# [bash] Verwaiste Symlinks suchen und finden?

## 3PO

Hallo Zusammen,

wie kann man denn mit bash ein Verzeichnis nach "toten" Symlinks durchsuchen und diese ggf. löschen?

----------

## Josef.95

Eventuell eignet sich auch 

```
app-misc/symlinks

     Available versions:  1.2-r2 {static}

     Homepage:            http://www.ibiblio.org/pub/linux/utils/file/

     Description:         Symlinks scans for and fixes broken or messy symlinks
```

für dein vorhaben?!

----------

## mv

```
find -L dir -type l
```

----------

## 69719

suchen

```

find -type l | while read LINK; do file "$LINK" | grep broken; done

```

löschen

```

rm $(find -type l | while read LINK; do file "$LINK" | grep broken; done | cut -d : -f 1)

```

----------

## mv

 *escor wrote:*   

> suchen
> 
> ```
> 
> find -type l | while read LINK; do file "$LINK" | grep broken; done
> ...

 

Sehr gefährlich, das: Erstens haben find | while read-Loops generell Probleme mit Leerzeichen in Filenamen. Zweitens ist "file" kein geeignetes Utility für Scripts, da es keinen standardisierte Output hat. Ein Link mit dem Namen "broken" wird hier beispielsweise ebenfalls gefunden.

Das simplere find dir -L type l  ist nach POSIX hingegen zuverlässig, solange es keine Symlinks auf Directories gibt: Die würde das Kommando wegen -L halt weiterverfolgen. Hier ist ein Script, das ich bei mir benutze, um die -L-Schwäche zu umgehen:

 *broken-links wrote:*   

> #! /bin/sh
> 
> exec find -H -- "${@}" -type l -exec /bin/sh -c "for i
> 
> do      readlink -q -e -- \"\${i}\" >/dev/null || printf '%s\\n' \"\${i}\"
> ...

 

----------

## 3PO

Vielen Dank für die zahreichen Tipps, aber so wie ich das sehe scheint das gar nicht so einfach zu sein.

----------

## 69719

 *mv wrote:*   

>  *escor wrote:*   suchen
> 
> ```
> 
> find -type l | while read LINK; do file "$LINK" | grep broken; done
> ...

 

Da es durch die pipe geleitet wird nicht, das Problem mit Leerzeichen kommt beim verwenden von "for in" Schleifen...

Read ließt Zeilenweise, nicht bis zum Leerzeichen.

```

for LINK in $(find -type l); do echo $LINK; done

```

Man könnte natürlich auch readlink -e verwenden, hatte nicht ins manual geschaut, dann würde es so aussehen.

```

find -type l | while read LINK; do readlink -e "$LINK" || echo "$LINK"; done

```

Und um beim löschen das problem mit Leerzeichen zu umgehen, dann folgendes verwenden.

```

find -type l | while read LINK; do readlink -e "$LINK" || rm "$LINK"; done

```

Wobei ich mich immer Frage, was Leerzeichen im Dateinamen zu suchen haben  :Wink: 

Ist eben Auslegungssache jedes einzelnen...

----------

## toralf

```
find -L / -type l

```

liefert auch alle /dev Einträge, also auch aus diesem Grunde is ein Pipen zu rm sehr gefährlich, oder ?

----------

## mv

 *escor wrote:*   

>  *mv wrote:*   Sehr gefährlich, das: Erstens haben find | while read-Loops generell Probleme mit Leerzeichen in Filenamen. 
> 
> Da es durch die pipe geleitet wird nicht, das Problem mit Leerzeichen kommt beim verwenden von "for in" Schleifen...

 

Ich meinte Leerzeichen im Sinne von [[:space:]]; im Fall von read gibt es das Problem dann bei returns im Filenamen; und ohne die Option -i gibt es wahrscheinlich auch noch Probleme mit anderen Zeichen wie \

Ich hatte ja extra mein Script gepostet: Dort wird es auf die einzig zuverlässige (kompatible) Art gemacht, mit der man find benutzen kann; nämlich mit -exec.

 *Quote:*   

> Man könnte natürlich auch readlink -e verwenden, hatte nicht ins manual geschaut

 

Das wird ja in meinem Script gemacht.

 *Quote:*   

> 
> 
> ```
> 
> find -type l | while read LINK; do readlink -e "$LINK" || rm "$LINK"; done
> ...

 

find ohne Angabe eines Directories ist deprecated. Und Weglassen von "--" vor dem Filenamen sollte man sich am Besten nicht angewöhnen. Zwar kann man bei den derzeitigen rm-Optionen (zumindest in GUN coreutils - wer weiß, wie es auf anderen Systemen ist) mangels eines zweiten Arguments zufälligerweise noch nicht viel Schaden anrichten, aber nach einem 

```
ln -s /nonexistent "

-rf"
```

 wird das Script zumindest merkwürdige Ausgaben tätigen.

 *Quote:*   

> Wobei ich mich immer Frage, was Leerzeichen im Dateinamen zu suchen haben 
> 
> Ist eben Auslegungssache jedes einzelnen...

 

Nein, keine Auslegungssache: Scripte haben zuverlässig zu laufen - Aufräum-Scripte vor allem dann, wenn man nicht weiß, wodurch vorher Files angelegt wurden. Scripte, die nur bei Neumond und nach Kippen von Salz über die Schulter tun, was sie sollen, will man doch nicht ernsthaft auf dem Rechner haben...

----------

## mv

 *toralf wrote:*   

> 
> 
> ```
> find -L / -type l
> 
> ...

 

/dev-Einträge im klassischen Sinn liefert es nicht. Aber durch das Verfolgen der Links landet dies im Pseudo-Filesystem /proc, in dem es sehr unklug ist, Links weiter zu verfolgen...

Dies gilt aber generell für alle Dinge: Auf /proc und /sys (und meist auch /dev) sollte man kein Programm loslassen, das nicht speziell dafür vorgesehen ist, da dort bereits das Lesen von Files merkwürdige Auswirkungen haben kann.

Und um es nochmals zu betonen: Pipen von find sollte man grundsätzlich unterlassen; der richtige Umgang mit find lautet -exec.

----------

## 3PO

 *mv wrote:*   

> [...]/dev-Einträge im klassischen Sinn liefert es nicht. Aber durch das Verfolgen der Links landet dies im Pseudo-Filesystem /proc, in dem es sehr unklug ist, Links weiter zu verfolgen...
> 
> Dies gilt aber generell für alle Dinge: Auf /proc und /sys (und meist auch /dev) sollte man kein Programm loslassen, das nicht speziell dafür vorgesehen ist, da dort bereits das Lesen von Files merkwürdige Auswirkungen haben kann. ...

 

In meinem Fall handelt es sich um ein Verzeichnis mit ca. 30000 Symlinks zu Bildern. Das Problem ist nun, dass häufig die "Originale" ersetzt, bzw. umbenannt oder auch gelöscht werden. Das wiederum hinterlässt eben "tote" Symlinks die einfach via Script suchen und entferen will.

----------

