1. Introduction
In this tutorial, we will see how to get the absolute directory of a given file using two common Linux file system tools.
2. Prerequisites
Unfortunately, there currently isn’t a single command to obtain the absolute directory of a file. Instead, we must break the operation into two parts, using the output of one command as the input for the other command.
2.1. readlink
To obtain the full path of a file, we use the readlink command. readlink prints the absolute path of a symbolic link, but as a side-effect, it also prints the absolute path for a relative path.
For example, suppose we have the following directory structure:
/
└── home/
└── example/
├── foo/
| └── file.txt
└── link -> foo/
We use the -f flag to canonicalize the path of either a relative path or a symbolic link. Therefore, if we change directory to /home/example/, we can execute any of the following commands:
readlink -f foo/file.txt
readlink -f link/file.txt
readlink -f ./foo/file.txt
readlink -f ../example/foo/file.txt
These commands will output:
/home/example/foo/file.txt
In the case of the first command, readlink resolves the relative path of foo/ to the absolute path of /home/example/foo/.
In the second case, readlink resolves the symbolic link of link/ to the same absolute path.
For the final two commands, readlink canonicalizes the relative paths and resolves to the same absolute path as the previous examples.
Note that the -f flag requires that all but the last component in the supplied path — file.txt in our case — must exist. If the path does not exist, no output is returned. For example, executing readlink -f bar/file.txt will produce no output since the bar/ directory doesn’t exist. In contrast, executing readlink -f foo/other.txt will return /home/example/foo/other.txt since all but the final component exists.
Instead, we can use the -m flag if we do not care if any of the components in the supplied path exists. Likewise, we can use the -e flag if we wish for all components in the supplied path to exist.
2.2. dirname
The second prerequisite is the dirname command, which prints the directory containing the supplied path.
If we supply a directory, dirname outputs the path containing that directory. For example, we can execute:
dirname /home/example/foo/
This will produce:
/home/example
Note that dirname prints the absolute directory because we supplied an absolute path. If we changed directory to /home/ and executed dirname example/foo/, dirname would output example. As a rule, if a relative path is provided, dirname will output a relative directory, and if an absolute path is provided, dirname will output an absolute directory.
When supplying a file, dirname outputs the path containing that file. For example, we can execute:
dirname foo/file.txt
This will produce:
foo
3. Absolute Directory of File
To obtain the absolute directory of a file, we combine the readlink and dirname commands. We can do this in one of two ways.
3.1. xargs
First, we can use the xargs command, which converts input into arguments for a supplied command. By piping the output from readlink into xargs and supplying the command dirname as an argument to xargs, we can obtain this desired absolute directory:
readlink -f foo/file.txt | xargs dirname
This results in:
/home/example/foo
3.2. Command Substitution
Similarly, we can use command substitution — $(command) — where a command is executed in a sub-shell, and the output from that command replaces its call. Therefore, we can execute the following:
dirname $(readlink -f foo/file.txt)
This command results in:
/home/example/foo
Equivalently, we could also execute the following command, and the output would remain the same:
dirname `readlink -f foo/file.txt`
Note that command substitution works with bash, but will not necessarily work with other shells.
4. Conclusion
In this tutorial, we looked at the readlink and dirname commands and how they can be used to obtain the absolute path of a relative path and the directory containing a path, respectively.
By combining these commands — either through xargs or command substitution — we can obtain the absolute directory of a file.