3

I know the thread and try to fix my find with -mindepth 15 unsuccessfully

find -L $HOME -type f -name "*.tex" \
   -exec fgrep -l "janne" /dev/null {} + | vim -R -

Unsuccessful attempt

find -L $HOME -type f -mindepth 15 -name "*.tex" \
   -exec fgrep -l "janne" /dev/null {} + | vim -R -
  • find -L about it here

Its STOUT

Vim: Reading from stdin...
find: ‘/home/masi/LOREM’: Too many levels of symbolic links

Visualization of symlinks unsuccessful which gives all files while I would like to see only symlinked directories and files in the system

tree -l

Law29's proposal

# include symlinks
find "$1" -type l -name "$2*" -print0 \
    | xargs -0 grep -Hr --include "*.tex" "$2" /dev/null {} + | vim -R -

Output unsuccessful but it should not be empty

Vim: Reading from stdin...
grep: {}: No such file or directory
grep: +: No such file or directory

Characteristics of the system

masi@masi:~$ ls -ld -- "$HOME" /home/masi/LOREM 
drwxr-xr-x 52 masi masi 4096 Aug 16 16:09 /home/masi
lrwxrwxrwx  1 masi masi   17 Jun 20 00:27 /home/masi/LOREM -> /home/masi/LOREM/

masi@masi:~$ type find
find is /usr/bin/find

masi@masi:~$ find --version
find (GNU findutils) 4.7.0-git
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Eric B. Decker, James Youngman, and Kevin Dalley.
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION FTS(FTS_CWDFD) CBO(level=2) 

System: Linux Ubuntu 16.04 64 bit
For for Script at the thread: here
Find: 4.7.0
Grep: 2.25
Application of find: haetex here

7
  • Why are you using -L? Can you not just do the find from the lowest common directory?
    – Law29
    Commented Jul 8, 2016 at 21:30
  • @Law29 Please, see the answer unix.stackexchange.com/a/293147/16920 why I am using find -L. Commented Jul 8, 2016 at 21:32
  • Why do you have /home/masi/LOREM as a symlink to itself? You will get the error "Too many levels of symbolic links" from any utility that attempts to dereference this circular link. Commented Aug 16, 2016 at 16:34
  • 1
    If you want to follow symbolic links with -L then you will get the error message, "Too many levels of symbolic links". If you don't want to follow the broken symbolic link (i.e. you use -H or nothing at all) then you won't get the error. Commented Aug 17, 2016 at 17:14
  • 1
    find won't follow infinite loops - it keeps track of the places it's already visited and won't use them a second time around. If you want to follow symlinks then you will get errors from entries like the one you've created with your LOREM file. The only way to avoid those is to redirect stderr away from the terminal (for example to /dev/null). Or to change the source code for find and have it not print the corresponding error message. Commented Aug 17, 2016 at 18:00

3 Answers 3

1
+100

If you want to display all files under $HOME, including those referenced via symbolic links, that end with .tex and contain the string janne:

find -L "$HOME" -type f -name '*.tex' -exec grep -l 'janne' {} + 2>/dev/null | vim -R -

If you want to display only symbolic links found under $HOME named *.tex corresponding to files that contain the string janne:

find -L "$HOME" -xtype l -name '*.tex' -exec grep -l 'janne' {} + 2>/dev/null | vim -R -

The only way to avoid the error message "Too many levels of symbolic links" is to discard all errors, which I've done with the 2>/dev/null construct.

In both cases the find verb will not traverse across files and directories that it has already traversed - it remembers where it's already visited and prunes those parts of the filesystem tree automatically. For example,

mkdir a a/b a/b/c
cd a/b/c
ln -s ../../../a

# Here you can ls a/b/c/a/b/c/a/b/...

# But find will not continue for very long
find -L a
a
a/b
a/b/c
find: File system loop detected; ‘a/b/c/a’ is part of the same file system loop as ‘a’.
3
  • @Masi - no... he offers you solutions that don't use the -L flag on find. Commented Aug 17, 2016 at 19:28
  • @Masi that's right, it isn't. I'm using /dev/null in a different way for a different purpose, though. And I'm offering you your -L flag. Commented Aug 18, 2016 at 5:53
  • 1
    @Masi -L follows all symlinks. -H only follows those at the top level. I used grep rather than fgrep because it doesn't matter in this instance. You could use fgrep if you preferred. Commented Aug 20, 2016 at 14:17
1

Your problem is that you have recursive symlinks. I would consider two options:

  • forget about the -L, get all the files named .tex anywhere in the tree, and then filter them (is there no other criteria than being in a directory that is pointed to by a symlink that starts with "Math"?)

  • Do it in two steps, both without -L: first you search for all symlinks named "Math*" (and maybe directories too?). You take that list and search for your tex files recursively from there, like this:

    find . -type l -name "Math*" -print0 \    
        | xargs -0 grep -Hr --include "*.tex" "janne"
    
2
  • Yes that's what it's supposed to do. I really do not understand why you have such a symlink structure though, nor why you have to respect it, not the why of this search. I would do a grep -r of the whole file-system if need be, and then manually look through the files I found.
    – Law29
    Commented Jul 9, 2016 at 5:31
  • 1
    I'm sorry, but I don't understand your problem at several levels. I hope someone else will be able to help you.
    – Law29
    Commented Jul 9, 2016 at 12:41
1

If the reason you're using -L is because $HOME is a symlink and you still want find to descend into it (but not in the other symlink to directories which would cause the problem you're running into), then use:

find "$HOME/" -name '*.tex' -type f -exec fgrep -l janne {} +

(/dev/null not needed with -l).

Or:

find -H "$HOME" -name '*.tex' -type f -exec fgrep -l janne {} +

That looks inside regular files only as generally, you don't want to look inside fifos, devices or directories. To also look inside symlinks to regular files (but then you'd be likely looking into the same file several times), you can change the -type f to -xtype f (assuming GNU find).

4
  • @Masi, what does ls -ld -- "$HOME" /home/masi/LOREN output? Commented Aug 16, 2016 at 12:27
  • 1
    @Masi, I can't reproduce your problem with find -H /home/masi -exec fgrep -l {} + with the same versions of those utilities. I can only reproduce it with find -H /home/masi/LOREM -exec fgrep -l {} as then we're explicitely asking find to resolve that broken symlink, which it can't do. Commented Aug 16, 2016 at 14:11
  • @Masi, but without -L, with find /home/masi, find will have no reason to resolve the LOREM symlink, so can't output that message. Without the -name '*.tex', or -type f, fgrep could complain about it, but not find, so I'm confused by your error message. Do you have an alias for find? What does type find tell you? Commented Aug 16, 2016 at 15:50
  • You are right! I went all my codes through again in a clean system. I also added my system info about find in the body. This command find -H "$1" -xtype f -name "*.tex" -exec fgrep -l $case_option "$2" {} + works and solves the case, passing also my test. - - Please, state any limitations etc about it. Commented Aug 16, 2016 at 16:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .