3 # findbl - find bad symbolic links (dangling, malformed etc.)
4 # Copyright © 2000-2006 by Pádraig Brady <P@draigBrady.com>.
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 # See the GNU General Public License for more details,
15 # which is available at www.gnu.org
20 # By default (-d) it reports dangling (stale) links. Note invalid
21 # pathnames are reported as stale by this script.
23 # To report redundant info in symbolic links, such as multiple
24 # consequtive ////'s or /./././ etc. you specify the -n option.
25 # Note that fixing this won't give you back any disk space as
26 # the link will take a disk block anyway, but malformed links
27 # like this could cause other programs problems.
29 # To report all absolute links in the specified path(s), use
30 # the -A option. This can help when you want to move a tree
31 # around in the filesystem.
33 # Likewise the -l option reports all relative links in the
36 # The -s option reports suspect absolute links. I.E. absolute
37 # links to files in the same directory as the link or below.
38 # TODO: support finding suspect relative link also. For e.g.:
39 # /etc/file.lnk ->../etc/file (python and abspath may be needed?)
41 # Note if this output passed to xargs or rm etc.
42 # then filenames with spaces will cause problems
44 # Should insert list of filesystems that support links
45 # or specify -xdev or something
47 # auto tidying of messy links could use tr -s / to squeeze consequtive /'s
48 # and sed s//..///d to remove /../
50 script_dir=`dirname $0` #directory of this script
51 script_dir=`readlink -f "$script_dir"` #Make sure absolute path
53 . $script_dir/supprt/fslver
56 ProgName=`basename "$0"`
57 echo "find \"Bad\" symbolic Links.
58 Usage: $ProgName [-d] [-s] [-l] [-s] [-n] [[-r] [-f] paths(s) ...]
60 These options are mutually exclusive (i.e. only the last one takes effect).
61 -d Dangling (or stale) links. This is the default mode
62 -s Suspect links (absolute links to paths within or below the link's directory)
65 -n reduNdant info in links (/././. ///// /../ etc.)
67 If no path(s) specified, then the current directory is assumed.
69 e.g. find dangling links in "library directories":
74 mode="dangling" #default
76 # Note must be careful with expressions (which are currently
77 # wrong I think), as the following are valid file/dir names:
78 # " ...", "..." etc. Hmm the symlinks program probably doesn't
79 # handle this correctly either?
81 ASC_01=`printf "\001"`
92 search_expr="${ASC_01}/" ;;
95 search_expr="${ASC_01}[^/]+" ;;
98 search_expr="(${ASC_01}.*[/]{2,})" #finds 2 or more consequtive /'s
99 search_expr="$search_expr|([${ASC_01}/]\./)" # starting with ./ or /./ anywhere
100 search_expr="$search_expr|(${ASC_01}.*[^.]+/[.][.]/)" #finds x/../y
101 search_expr="$search_expr|(${ASC_01}/[.][.]/)" #finds /../y
102 search_expr="$search_expr|(${ASC_01}.*[.]{3,}/[.][.]/)" #finds .../../y etc
103 search_expr="$search_expr|(${ASC_01}.+/$)" ;; #finds ending with /
109 argsToPassOn="$argsToPassOn '$arg'" ;;
113 . $script_dir/supprt/getfpf "$argsToPassOn"
117 find "$@" -type l -printf "$FPF\n" |
118 #perl -nle '-e || print' | #this is much faster than below
119 #/usr/share/dict/words is 45424 lines which is 0.12s for
120 #perl and 3.8s for shell while read! should be OK though?
121 #Note also this doesn't distinguish EPERM and ENOENT
122 while read file; do [ -e "$file" ] || echo $file; done |
124 xargs -r0 ls -lUd -- |
125 sed 's/.*[0-9]\{2\} \(.*\)/\1/' ;; #only leave link -> target
127 find "$@" -type l -printf "$FPF ->\1%p\1%l\n" |
128 grep "${ASC_01}.*${ASC_01}/" | #get absolute links
129 sed -e "s¬${ASC_01}./¬${ASC_01}$PWD/¬g" | #change rel to abs paths
130 grep -E "${ASC_01}(.*)/[^/]+${ASC_01}\1" | #find suspect links
131 sed -e "s¬${ASC_01}.*${ASC_01}¬ ¬g" ;; #drop work column
132 absolute|relative|redundant)
133 find "$@" -type l -printf "$FPF ->\1%l\n" |
134 grep -E "$search_expr" |