I am collecting all the files under a directory. But this directory has symlinks to other directory outside of the directory where I am running the find command and it contains huge number of files as well as directories. Though I can ignore this directory with the help of prune, the problem arises when a symlinks point to a child directory of this huge directory. I want to ignore all the symlinks which points to any on the child directories.
Here is a sample command find -L /usr/local/searchdir
Few symlinks
/usr/local/searchdir/d0/link --> /small/dir
/usr/local/searchdir/d1/file.o
/usr/local/searchdir/d2/link --> /little/dir
/usr/local/searchdir/d3/link --> /hugedir
/usr/local/searchdir/d4/link --> /hugedir/main
.
.
.
/usr/local/searchdir/dx --> /hugedir/c4
Problematic directories
/hugedir/c1/tmp
/hugedir/c2/main
/hugedir/c3/dir
/hugedir/c4/ext
/hugedir/c5/client
/hugedir/c6/bin
/hugedir/c7/std
2 Answers 2
GNU find
has a -lname
option to match on the target of a symlink but it can't be used with -L
/-follow
.
Assuming you do want to use -L
, you'd need to call -exec
to implement your own check that the link is on that large dir.
Here using GNU find
's -xtype
as an optimisation as assuming your system has a readlink
and that it supports the -f
option a la GNU readlink
:
find -L . -type d -xtype l -exec sh -c '
case $(readlink -f "1ドル") in
(/hugedir | /hugedir/*) exit 0;;
(*) exit 1;;
esac' sh {} \; -prune -o ...
Or slightly more efficient.
find -L . -type d -xtype l -exec sh -c '
cd -P "1ドル" && case $PWD in
(/hugedir | /hugedir/*) exit 0;;
(*) exit 1;;
esac' sh {} \; -prune -o ...
-
+1 Nice one Stéphane, especially the use of
1ドル
in compbination with-exec
and{}
. However had you not better make use of-execdir
?Cbhihe– Cbhihe2016年09月16日 14:24:42 +00:00Commented Sep 16, 2016 at 14:24 -
1@Cbhihe, with
-execdir cmd
,cmd
's current working directory would be the directory that contains the symlink, so you'd still need to do acd -P
(evencd -P --
with FreeBSDfind
, though FreeBSD find doesn't have the-printf
that the OP is using). With-L
,-execdir
doesn't really add the security benefit that it does when not using-L
.Stéphane Chazelas– Stéphane Chazelas2016年09月16日 14:28:39 +00:00Commented Sep 16, 2016 at 14:28
The find
command by default does ignore symlinks. You can anyway specify explicitly this behaviour via the -P
flag:
-P Never follow symbolic links. This is the default behaviour. When find examines or prints information a file, and the file is a symbolic link, the information used shall be taken from the
properties of the symbolic link itself.
-L Follow symbolic links. When find examines or prints information about files, the information used shall be taken from the properties of the file to which the link points, not from the link
itself (unless it is a broken symbolic link or find is unable to examine the file to which the link points). Use of this option implies -noleaf. If you later use the -P option, -noleaf will
still be in effect. If -L is in effect and find discovers a symbolic link to a subdirectory during its search, the subdirectory pointed to by the symbolic link will be searched.
When the -L option is in effect, the -type predicate will always match against the type of the file that a symbolic link points to rather than the link itself (unless the symbolic link is
broken). Using -L causes the -lname and -ilname predicates always to return false.
-H Do not follow symbolic links, except while processing the command line arguments. When find examines or prints information about files, the information used shall be taken from the proper‐
ties of the symbolic link itself. The only exception to this behaviour is when a file specified on the command line is a symbolic link, and the link can be resolved. For that situation,
the information used is taken from whatever the link points to (that is, the link is followed). The information about the link itself is used as a fallback if the file pointed to by the sym‐
bolic link cannot be examined. If -H is in effect and one of the paths specified on the command line is a symbolic link to a directory, the contents of that directory will be examined
(though of course -maxdepth 0 would prevent this).
-
I have -L added in the command as I need to follow symlinks but I don't want to follow them when they are pointing to any of the children directories of a special directory. Since there are many symlinks pointing to children of this special directory, it is very difficult exclude or prune them with any pattern.Rakesh– Rakesh2016年09月15日 09:16:52 +00:00Commented Sep 15, 2016 at 9:16
-prune
?