How to see full absolute path of a symlink
realpath
isn't available on all linux flavors, but readlink
should be.
readlink -f symlinkName
The above should do the trick.
Alternatively, if you don't have either of the above installed, you can do the following if you have python 2.6 (or later) installed
python -c 'import os.path; print(os.path.realpath("symlinkName"))'
Bash: how to get real path of a symlink?
readlink
is not a standard command, but it's common on Linux and BSD, including OS X, and it's the most straightforward answer to your question. BSD and GNU readlink implementations are different, so read the documentation for the one you have.
If readlink
is not available, or you need to write a cross-platform script that isn't bound to a specific implementation:
If the symlink is also a directory, then
cd -P "$symlinkdir"
will get you into the dereferenced directory, so
echo "I am in $(cd -P "$symlinkdir" && pwd)"
will echo the fully dereferenced directory. That said, cd -P
dereferences the entire path, so if you have more than one symlink in the same path you can have unexpected results.
If the symlink is to a file, not a directory, you may not need to dereference the link. Most commands follow symlinks harmlessly. If you simply want to check if a file is a link, use test -L
.
How to obtain the full PATH, *allowing* for symbolic links
If all you want to do is to make an absolute path that has minimal changes from a relative path then a simple, safe, and fast way to to it is:
[[ $dest_dir == /* ]] || dest_dir=$PWD/$dest_dir
(See Correct Bash and shell script variable capitalization for an explanation of why dest_dir
is preferable to DEST_DIR
.)
The code above will work even if the directory doesn't exist (yet) or if it's not possible to cd
to it (e.g. because its permissions don't allow it). It may produce paths with redundant '.' components, '..' components, and redundant slashes (`/a//b', '//a/b/', ...).
If you want a minimally cleaned path (leaving symlinks unresolved), then a modified version of your original code may be a reasonable option:
dest_dir=$(cd -- "$dest_dir"/ && pwd)
- The
--
is necessary to handle directory names that begin with '-'. - The quotes in
"$dest_dir"
are necessary to handle names that contain whitespace (actually$IFS
characters) or glob characters. - The trailing slash on
"$dest_dir"/
is necessary to handle a directory whose relative name is simply-
. - Plain
pwd
is sufficient because it behaves as if-L
was specified by default.
Note that the code will set dest_dir
to the empty string if the cd
fails. You probably want to check for that before doing anything else with the variable.
Note also that $(cd ...)
will create a subshell with Bash. That's good in one way because there's no need to cd
back to the starting directory afterwards (which may not be possible), but it could cause a performance problem if you do it a lot (e.g. in a loop).
Finally, note that the code won't work if the directory name contains one or more trailing newlines (e.g. as created by mkdir $'dir\n'
). It's possible to fix the problem (in case you really care about it), but it's messy. See How to avoid bash command substitution to remove the newline character? and shell: keep trailing newlines ('\n') in command substitution. One possible way to do it is:
dest_dir=$(cd -- "$dest_dir"/ && printf '%s.' "$PWD") # Add a trailing '.'
dest_dir=${dest_dir%.} # Remove the trailing '.'
How to get full path of a file?
Use readlink:
readlink -f file.txt
Related Topics
Check If a Variable Exists in a List in Bash
How to Remove the Bom from a Utf-8 File
Creating a Bootable Iso Image with Custom Bootloader
Using Grep and Sed to Find and Replace a String
How to Increase Neo4J's Maximum File Open Limit (Ulimit) in Ubuntu
Running Shell Script in Parallel
Signing Windows Application on Linux-Based Distros
How to Monitor a Complete Directory Tree for Changes in Linux
Difference Between Pid and Tid
Insert Multiple Lines into a File After Specified Pattern Using Shell Script
How to Increase Ble Advertisement Frequency in Bluez
Extract Lines Between Two Patterns from a File
Using "$Random" to Generate a Random String in Bash
What Do the Numbers in /Proc/Loadavg Mean on Linux
What's the Purpose of Each of the Different Uids a Process Can Have