In this tutorial, we will see how to get the absolute directory of a given file using two common Linux file system tools.
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.
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:
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.
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:
This will produce:
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:
This will produce:
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.
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:
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:
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.
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.