Linux dirname Command: Extract the Directory Part of a Path

dirname is a command that removes the last filename or directory name from a path string and outputs the preceding directory part. It is useful in shell scripts to determine the parent path of a file or to process a path by splitting it along with basename.

dirname does not actually traverse the file system or check for the existence of parent directories. It applies predetermined rules to the input string, so if you need to resolve actual absolute paths or symbolic links, you should use a command like realpath.

What is the dirname command?

To get the part of a full path excluding the last component, run it as follows.

dirname /home/user/report.txt

The output is as follows.

/home/user

It does not check whether the last name entered is an actual file or directory. Since it is simple string processing, the same rules apply even to paths that do not exist.

Basic Syntax and Usage

dirname name...

GNU dirname can take multiple paths and output each result on a separate line.

dirname /var/log/nginx/access.log
dirname /home/user/Documents/
dirname relative/path/file.txt

Typical results are /var/log/nginx, /home/user, and relative/path respectively. Trailing slashes and consecutive slashes may change during the cleanup process, so do not use it to preserve the original string as is.

Results by input type

Input General output
/home/user/report.txt /home/user
docs/manual.pdf docs
notes.txt .
/usr/ /
/ /

Name without a slash

If there is no slash in the input, a single dot representing the current directory is printed.

dirname report.txt
.

This result does not mean that a file named report.txt actually exists in the current directory; it represents the directory part in the input string.

Absolute path and root path

If the last component of an absolute path is removed and only the root remains, / is printed.

dirname /etc
dirname /

Both commands generally print /. Even if the parent of the root is expressed as a string, it is still the root itself.

Trailing slash in the path

The unnecessary trailing slash is removed first, and then the last component is processed.

dirname /srv/www/site/
dirname /srv/www/site///

Both inputs generally output /srv/www. This is not suitable for tasks that need to preserve the number of slashes or a trailing slash in the original.

Processing Multiple Paths

Specifying multiple names at once

In the GNU implementation, multiple paths can be listed.

dirname /srv/www/index.html /var/log/syslog /home/user/file.txt

The directory part for each input is output on a separate line.

/srv/www
/var/log
/home/user

Separate with NUL using -z

In automation where filenames may contain line breaks, you can separate the results with a NUL character using -z or --zero.

dirname -z /srv/www/index.html /var/log/syslog

Since this option is a GNU extension, check for support if you need to run it on other Unix-like systems.

Using dirname and basename together

You can extract the directory part and the last name from a path separately.

path='/home/user/docs/report.pdf'
directory=$(dirname -- "$path") || exit 1
name=$(basename -- "$path") || exit 1

printf 'Directory: %s\n' "$directory"
printf 'Name: %s\n' "$name"

The output takes the following form.

Directory: /home/user/docs
Name: report.pdf

These two commands are convenient for splitting the original string into two meaningful parts, but when combined again, they do not restore duplicate slashes or a trailing slash from the original.

Using in shell scripts

Creating the parent directory of an output file

You can prepare the parent directory before creating a file.

output='/srv/backups/daily/archive.tar.gz'
output_dir=$(dirname -- "$output") || exit 1
mkdir -p -- "$output_dir"

If the input path is untrusted, you should separately verify that it does not go outside the desired base directory. The dirname itself does not restrict access.

Comparing with POSIX Shell Parameter Expansion

For simple input, you can remove the last part after a slash using shell parameter expansion.

path='/srv/www/index.html'
directory=${path%/*}
printf '%s\n' "$directory"

However, names without slashes, the root path, or paths with a trailing slash may produce different results from dirname. If the input forms vary, thoroughly test the exceptions in your custom expansion.

differences between dirname, realpath, and pwd

Command Target for processing Main result
dirname Entered path string String excluding the last name
basename Entered path string Last file name or directory name
realpath Specified path and file system Normalized path or path with symbolic links resolved
pwd Current working location of the process Absolute path of the current working directory

dirname../logs/app.log outputs ../logs as a string. It does not convert it to an absolute path relative to the current location or resolve symbolic links.

Summary of major options

Option Description
-z, --zero End each result with a NUL character instead of a newline.
--help Displays usage and supported options.
--version Prints the installed GNU Coreutils version.
-- Subsequent arguments are treated as names, not options.

Common issues

Result is a single dot

Because the input name does not contain a slash. The result of dirname file.txt, which is ., represents the current directory from a string perspective.

Parent directory does not actually exist

dirname does not check the file system. To actually use the output directory, you need to separately verify its existence and access permissions.

Paths with spaces or wildcards break

Enclose variables in double quotes and use -- before values that can start with a hyphen.

dirname -- "$path"

FAQ

Does dirname actually find the parent directory?

No. It only removes the last component from the input path string; it does not check the actual existence of the path or symbolic links.

Why does dirname file.txt print a single dot?

Because there is no slash separating a directory in the input, it prints . representing the current directory.

Can multiple paths be processed at once?

GNU dirname accepts multiple paths as arguments and prints each result. If portability with other Unix implementations is needed, check the supported format first.

Can I use dirname if I need an absolute path?

dirname does not convert relative paths to absolute paths. If you need a normalized absolute path, use the appropriate realpath option.

Related articles and official documentation

More in This Category
Linux umask Command: Control Default File Permissions

Linux umask Command: Control Default File Permissions

Learn how to control Default File Permissions with the Linux umask command, including practical examples, key options, and important precautions.

Linux kill Command: Send a Signal to a Process ID

Linux kill Command: Send a Signal to a Process ID

Learn how to send a Signal to a Process ID with the Linux kill command, including practical examples, key options, and important precautions.

Linux pacman Command: Manage Packages on Arch Linux

Linux pacman Command: Manage Packages on Arch Linux

Learn how to manage Packages on Arch Linux with the Linux pacman command, including practical examples, key options, and important precautions.

Linux ssh-copy-id Command: Install a Public Key on a Remote Account

Linux ssh-copy-id Command: Install a Public Key on a Remote Account

Learn how to install a Public Key on a Remote Account with the Linux ssh-copy-id command, including practical examples, key options, and important precautions.

Linux last Command: Review Login and Reboot History

Linux last Command: Review Login and Reboot History

Learn how to use the Linux last command to review user login sessions, system reboots, and shutdown history, with essential options, practical examples, output interpretation, and common troubleshooting tips.

Linux Tutorial / File Types and Metadata: ls, file, stat, and readlink

Linux Tutorial / File Types and Metadata: ls, file, stat, and readlink

Learn what ls, file, stat, and readlink each reveal about a Linux file, including type, size, timestamps, and symbolic-link targets.

Linux fsck Command: Check and Repair Filesystems

Linux fsck Command: Check and Repair Filesystems

Learn how to check and Repair Filesystems with the Linux fsck command, including practical examples, key options, and important precautions.

Linux machine-id: How to Check and Reset It for Cloned Systems

Linux machine-id: How to Check and Reset It for Cloned Systems

Learn what the Linux machine-id identifies, how to check it, and how to prepare cloned system images for unique IDs. Understand the difference between an empty file and first-boot initialization.

Linux lscpu Command: Inspect CPU Architecture and Cores

Linux lscpu Command: Inspect CPU Architecture and Cores

Learn how to inspect CPU Architecture and Cores with the Linux lscpu command, including practical examples, key options, and important precautions.

Linux resolvectl Command: Inspect systemd DNS Resolution

Linux resolvectl Command: Inspect systemd DNS Resolution

Learn how to inspect systemd DNS Resolution with the Linux resolvectl command, including practical examples, key options, and important precautions.