2

I sometimes want to know where an original/real file is on my system that is linked via multiple symlinks to a known handle. Running ls -l /path/to/file will show me the location of the next link, but if I want to track down the original then I find myself copy-pasting a bunch of paths, which is cumbersome.

Is there a more direct way (viz. single shortish command) to go straight from A to Z? Or do I have to build a function that sequentially works through each link till we reach the final 'real' file? (Suggestions for such a function are welcome!)

Example case: I wanted to find all of the postgresql executables installed together on centos. To do that, I had to burrow down the following rabbit hole:

which psql
> /usr/bin/psql
ls -l /usr/bin/psql 
> l.......... ... /usr/bin/psql -> /etc/alternatives/pgsql-psql*
ls -l /etc/alternatives/pgsql-psql
> l.......... ...  /etc/alternatives/pgsql-psql -> /usr/pgsql-11/bin/psql*
ls -l /usr/pgsql-11/bin/psql
> -.......... ... /usr/pgsql-11/bin/psql*
ls /usr/pgsql-11/bin/
> [Voila!]

Is there an easier (and generalizable) way to get from psql -> /usr/pgsql-11/bin/?

Magnus
  • 3,086
  • 2
  • 29
  • 51
  • Similar question [here](/q/3572030), with comments linking to more similar questions. One solution is to install GNU realpath via `brew install coreutils`, another to write a small [wrapper program](/a/46772980) around the [realpath syscall](https://www.unix.com/man-page/osx/3/realpath). – cachius Nov 14 '22 at 12:56

1 Answers1

3

You can use realpath to recursively resolve all symlinks and give you a canonical path:

$ cd /tmp
$ touch baz
$ ln -s baz bar
$ ln -s bar foo

$ ls -l foo
lrwxrwxrwx 1 me me 3 Nov 20 09:42 foo -> bar

$ realpath foo
/tmp/baz
that other guy
  • 116,971
  • 11
  • 170
  • 194