I have this:

read_link="$(readlink "$file_path")"  # just in case it's a symlink

readlink will echo an empty string if it's not a symlink? Is there an option to readlink that will just echo the original path if it's not a symlink?


For a GNU/Linux system, the -f flag to readlink (--canonicalize), « canonicalize by following every symlink in every component of the given name recursively » will do this for you:

touch /tmp/real
ln -s /tmp/real /tmp/link

readlink -f /tmp/real    # → "/tmp/real"
readlink -f /tmp/link    # → "/tmp/real"

For a Mac OSX system, there is no option to do this, « If the given argument is not a symbolic link, readlink will print nothing and exit with an error ».

For both systems you can find the documentation and all available options for readlink with man readlink.

The closest you can get is to a general-purpose solution on OSX is something like this function

readlinkorreal() { readlink "$1" || echo "$1"; }

readlinkorreal /tmp/real    # → "/tmp/real"
readlinkorreal /tmp/link    # → "/tmp/real"
| improve this answer | |
  • 1
    I didn't downvote, this works, if someone did downvote perhaps it's because they think the -m or -e option could work? I think your wrapper func makes sense – Alexander Mills Aug 6 '19 at 16:41

Given the following file structure:

├── link -> no-link
└── no-link

The -m option seems to do the trick.

florin@debian:/tmp/test$ readlink -m link 
florin@debian:/tmp/test$ readlink -m no-link 

| improve this answer | |

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.