How to convert ".." in path names to absolute name in a bash script?

Try:

ABSOLUTE_PATH=$(cd /home/nohsib/dvc/../bop; pwd)

What you're looking for is readlink:

absolute_path=$(readlink -m /home/nohsib/dvc/../bop)

Please note: You need to use GNU's readlink implementation which offers the "-m" option. BSD's readlink for example does not.


If you want to do it without following any symlinks, then try using realpath with option -s:

$ realpath -s /home/nohsib/dvc/../bop
/home/nohsib/bop

Note that with realpath, normally all but the last component must exist. So for the above to work, the following must all be present in the file system:

/home
/home/nohsib
/home/nohsib/dvc

But you can bypass that requirement using the -m option.

$ realpath -sm /home/nohsib/dvc/../bop
/home/nohsib/bop

(Note realpath is not available on all systems, especially older non-Debian systems. For those working on embedded Linux, unfortunately Busybox realpath doesn't support the -s or -m switches.)


One issue with using :

ABSOLUTE_PATH=$(cd ${possibleDirectory}; pwd)

is that if ${possibleDirectory} doesn't exist, ABSOLUTE_PATH will then be set to the current directory. Which is probably NOT what you want or expect.

I think using this version may be more desirable in general:

ABSOLUTE_PATH=$(cd ${possibleDirectory} && pwd)

If ${possibleDirectory} does not exist or is not accessible, due to missing directory access permissions, ABSOLUTE_PATH will contain the empty string.

The advantage of this is that you can then test for the empty string or let it fail naturally, depending on the circumstances. Defaulting to the current directory in the case of a failed 'cd' command may lead to very unexpected and possibly disastrous results (e.g. rm -rf "$ABSOLUTE_PATH" )

Tags:

Linux

Unix

Bash