I usually do a find with an environment variable as the path when searching for source code. Recently I replaced my environment variable with a symbolic link, and it broke Bash's shell completion. When I do a find using the symlink it doesn't work, but if I use the actual path that the symlink points to, it works find.

ln -s /some/source/dir /the/source
export SYMLINK=/the/source
export DIR=/some/source/dir

find $SYMLINK -name file.c        // doesn't find anything
find $DIR -name file.c            // works as expected

In this example $SYMLINK is a symbolic link for $DIR's value.

So, why does bash handle symlink environment variables differently?


It's not bash, it's find; though you'll find that most utilities will follow the same principle:

  • If operating on file contents, a symlink to a regular file is equivalent to the actual file.
  • If operating on directory entries, symlinks are a category of their own.

When you run find $SYMLINK, find sees an object that isn't a directory, so it doesn't traverse it. If you want to treat a symlink to a directory as if it was that directory, add a / at the end (a few broken systems or commands may require "$SYMLINK/."):

find "$SYMLINK/" -name file.c

For find, you can also use the -H option, which tells it to treat any symlink on the command line as if you had specified the target:

find -H "$SYMLINK" -name file.c

It's not bash, it's find. Following symlinks in a recursive directory traversal often leads to infinite loops (consider the common trick of ln -s foo . to provide a compatibility path). POSIX find includes the -follow predicate to override this; perhaps more usefully in this case, GNU find provides -H to follow only symlinks directly specified as parameters, while continuing to avoid expanding symlinks found during traversal. You could use these with an alias:

alias find='find -H'
  • 1
    For -follow and -H, it's the opposite: -H is POSIX, -follow is a GNU (and other) extension. – Gilles Jun 3 '11 at 16:26
  • @Gilles: huh, I admit to not checking the POSIX standard specifically but -follow predates POSIX. – geekosaur Jun 3 '11 at 16:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.