What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Unix and Linux directory management is handled by a set of shell commands: pwd and cd navigate, ls inspects, mkdir creates, cp copies, mv moves or renames, rmdir removes empty directories, rm -r removes directory trees, and find searches them. du measures directory usage, while df reports free space on the containing filesystem.

This guide focuses on safe, practical usage, including paths, permissions, symbolic links, unusual filenames, destructive operations, and the differences between portable Unix syntax and GNU/Linux extensions.

Quick reference

Task Command Example Portability
Show current directory pwd pwd -P Portable; logical and physical modes can vary
Change directory cd cd -- "$HOME/projects" Shell built-in
List contents ls ls -la Portable basics; options vary
Create directories mkdir mkdir -p project/src Widely portable
Remove an empty directory rmdir rmdir empty Portable
Remove a directory tree rm -r rm -ri -- old-tree Portable basics; dangerous
Copy a directory cp cp -a source destination -a is common GNU/BSD syntax
Move or rename mv mv -- old new Portable basics
Search a tree find find . -type d -name 'cache' Predicates vary
Measure directory usage du du -sh directory Options vary
Check filesystem space df df -h /path Portable basics; formatting options vary

Linux commonly supplies GNU Coreutils. Other Unix-like systems, including macOS and BSD systems, may use different implementations and option names. The GNU Coreutils documentation currently describes version 9.11; installed distributions may ship older or patched versions. See the GNU Coreutils manual and Linux command introduction.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Understand paths before running commands

An absolute path starts at the root directory, such as /var/log. A relative path starts from the current working directory, such as logs or ../backup. The root directory is /; ~ normally means the current user’s home directory; . means the current directory; and .. means its parent.

Names beginning with a dot are hidden by convention. They are still directory entries, so a directory containing only .config is not empty. A directory can also be a mount point for another filesystem or contain symbolic links to other locations.

The shell expands variables, quotes, and glob characters before most commands run. For example, * is expanded by the shell, while expressions such as -name '*.log' are interpreted by find. Quote paths and patterns:

mkdir -p -- "$HOME/projects/demo"
find . -type d -name '*.cache'

Quoting protects spaces, tabs, wildcard characters, and many unusual names. The -- marker ends command options where supported, protecting a pathname that begins with -.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Navigate with pwd and cd

pwd
pwd -P
pwd -L
cd /var/log
cd ..
cd ~
cd -
cd

pwd prints the current working directory. pwd -P requests a physical path with symbolic links resolved; pwd -L requests the logical path maintained by the shell. Use the option explicitly when symlink resolution matters.

cd with no argument normally changes to the home directory. cd - returns to the previous directory using $OLDPWD. Because cd changes the current shell’s working directory, it is normally a shell built-in: an external process cannot change its parent shell’s directory. A cd inside a separate script or pipeline therefore does not change the directory of the calling shell.

target="$HOME/projects/demo"
cd -- "$target" || exit 1
printf 'Now in: %sn' "$PWD"

If cd fails, the working directory does not change. Check it with pwd or printf '%sn' "$PWD".

List and inspect directories with ls

ls
ls -l
ls -la
ls -A
ls -ld -- project
ls -lh
ls -ltr

ls project lists the contents of project. ls -d project lists the directory entry itself, and ls -ld project displays its metadata without listing inside it. The -a option includes . and ..; -A includes hidden entries except those two. Long format shows mode, link count, owner, group, size, timestamp, and name. A leading d indicates a directory and l a symbolic link.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Do not parse ordinary ls output in scripts. Names can contain whitespace, tabs, quotes, and newlines, and formatting changes with options and terminals. Use shell globs with careful handling or find instead.

Create directory trees with mkdir

mkdir project
mkdir project/src project/tests
mkdir -p -- project/src/main
mkdir -m 750 -- private

Without -p, parent directories must already exist. With -p, missing parents are created and existing parents are not treated as an error. The process umask affects initial permissions, so -m is a requested mode rather than a reason to assume every platform produces identical results. If exact final permissions matter, verify and use chmod afterward.

mkdir -p -- "$HOME/projects/demo/src"
chmod 750 -- "$HOME/projects/demo"

Copy, move, and rename directories

cp: copy a directory

cp -r source-dir destination-dir
cp -a -- source-dir destination-dir
cp -a -- source-dir/. destination-dir/

cp -r recursively copies a tree. cp -a, common on GNU and BSD systems, attempts to preserve a broad set of attributes and links. It does not guarantee preservation of every ACL, extended attribute, security label, sparse-file detail, hard-link relationship, ownership detail, or filesystem-specific feature.

Destination layout matters. If the destination already exists as a directory, the source may be placed inside it. The forms cp -a source destination and cp -a source/. destination/ can produce different nesting results. Verify the result:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
find -- destination -maxdepth 2 -print
du -sh -- source-dir destination

-i can ask before overwriting; -n is available on some implementations. For large transfers requiring restart or progress features, rsync may be more suitable where installed.

mv: move or rename

mv -- old-name new-name
mv -i -- project /srv/projects/

Renaming within one directory is a move operation. On the same filesystem, a rename normally changes directory entries without copying the contents or changing their inode identities. Across filesystems, an implementation may need to copy and then remove the original.

Inspect both operands before moving. An existing destination can cause unexpected nesting or overwriting, depending on the implementation and options. GNU’s -T option can force a destination to be treated as a normal path rather than a directory, but it is not portable.

Remove directories safely

Use rmdir for empty directories

rmdir -- empty-dir
rmdir -p -- a/b/c

rmdir removes only empty directories. It fails when visible or hidden entries remain. The -p form, where supported, also attempts to remove empty parent directories.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use recursive rm only after inspection

find -- old-tree -mindepth 1 -maxdepth 1 -print
rm -ri -- old-tree

rm -r recursively attempts to remove a directory and its contents. rm -i requests confirmation in situations supported by the implementation. rm -f
aaa
suppresses many prompts and nonexistent-file errors, and rm -rf combines force and recursion. It is dangerously destructive and should not be the default beginner command.

A trailing slash does not make deletion safe. Never use unvalidated variables in recursive deletion. A safer script should reject empty or obviously dangerous targets:

target="/path/to/remove"
case $target in
  ""|/|"$HOME") printf '%sn' 'Refusing unsafe target' >& exit 1 ;;
esac
rm -ri -- "$target"

Before removing a large tree, inspect symbolic links, mounts, and filesystem boundaries. On Linux, findmnt --target /path/to/tree can help identify the mounted filesystem. Recursive operations can still be affected by concurrent changes and permissions.

Search directory trees with find

find . -type d
find /var -type d -name 'cache'
find . -type d -empty
find . -type d -mtime +30
find . -type d -name 'build' -print

-type d selects directories, -name matches a basename, and -path matches a path. Quote patterns so the shell does not expand them. -maxdepth, -mindepth, -prune, and -delete are common GNU/BSD extensions rather than universal POSIX predicates.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Preview results with -print before taking action:

find . -type d -name 'build' -print
find . -type d -name 'build' -exec rm -r -- {} +

-exec ... {} + batches results; -exec ... {} ; runs once per result. Null-delimited output handles unusual names:

find . -type d -print0 |
  while IFS= read -r -d '' dir; do
    printf '%sn' "$dir"
  done

The read -d form is Bash-specific. Avoid for f in $(find ...); command substitution splits names on whitespace and cannot safely represent newlines.

Measure usage: du versus df

du -sh -- directory
du -h --max-depth=1 -- directory
df -h /path/to/directory

du estimates space used by a directory tree, usually in allocated filesystem blocks. du -s summarizes and -h uses human-readable units. df reports used and available capacity for the filesystem containing a path. A small du result does not prove that the filesystem has free space: other directories, reserved blocks, snapshots, metadata, or deleted-but-open files may account for the difference.

Use du -x, where supported, to stay on one filesystem. Avoid relying on directory/* when hidden entries matter; shell globbing does not normally include dotfiles.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Directory permissions and ownership

ls -ld -- directory
chmod 750 -- directory
chmod u+rwx,g+rx,o-rwx -- directory
chown user:group -- directory
chgrp developers -- directory

Directory permission bits have special meanings:

  • Read (r) allows listing names.
  • Write (w) allows creating, removing, or renaming entries, subject to other restrictions.
  • Execute (x) allows searching or traversing the directory and accessing known names.

Write permission without execute permission is usually insufficient for useful entry manipulation. Removing a file generally depends on permissions on its containing directory, not only on the file. Access can also be affected by ACLs, capabilities, read-only mounts, SELinux, AppArmor, and network filesystem behavior.

The sticky bit is commonly used on shared writable directories:

chmod 1777 -- shared-directory

A setgid directory can cause newly created entries to inherit its group where supported:

chmod 2770 -- shared-directory

Ownership changes generally require elevated privileges. Avoid broad commands such as sudo chmod -R or sudo chown -R until the exact scope, desired modes, and consequences are understood. Recursive changes can break services, executable files, SSH access, ACLs, and security labels.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Symbolic and hard links

ln -s /opt/app/current app
ln existing-file hard-link
ls -l app
readlink app
readlink -f app
realpath app

A symbolic link stores a path and may point to a file or directory. A hard link refers to the same inode; it normally cannot cross filesystems and ordinary users generally cannot create hard links to directories. Relative symbolic-link targets are interpreted relative to the directory containing the link, not necessarily the caller’s current directory.

cd follows directory symlinks, which is why logical and physical paths can differ. rm link-name removes the link, not its target. Broken links remain directory entries. Inspect links before copying or deleting trees, because link handling depends on the command, implementation, and operand position.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Archive directory trees with tar

tar -cf project.tar project/
tar -tf project.tar
tar -xf project.tar
tar -czf project.tar.gz project/
tar -xzf project.tar.gz

An archive packages a tree; it is not a live copy of the directory. List an archive before extracting it, and extract untrusted archives into a controlled destination. Path traversal, ownership restoration, permissions, and compression flags vary by implementation and privilege level; the examples reflect common GNU tar usage.

Portable Unix syntax versus GNU/Linux conveniences

Feature Qualification
mkdir -p Widely available and standard in modern Unix environments.
cp -a Common GNU/BSD extension; verify on strict POSIX systems.
find -maxdepth and -delete Common but not universal.
du --max-depth GNU-style option.
Long options such as --help Not guaranteed by historical Unix utilities.
findmnt Linux-specific.
Bash pipefail and read -d Shell-specific, not POSIX sh syntax.

For scripts intended to run across Unix-like systems, use conservative POSIX syntax and verify options against the target system’s manual pages. For GNU/Linux administration, GNU extensions can be practical, but label them clearly.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Practical workflows

Create and inspect a project tree

pwd
ls -la
mkdir -p -- "$HOME/projects/demo/src"
cd -- "$HOME/projects/demo/src" || exit 1
pwd
cd ../.. || exit 1
ls -ld -- "$HOME/projects/demo"

Copy a directory as a backup

cp -a -- project project.backup
find -- project.backup -maxdepth 2 -print
du -sh -- project project.backup

Find empty directories

find . -type d -empty -print

Review the printed list before adding a deletion action. Empty directories can be intentional, including mount points or application placeholders.

Find large subdirectories

du -h --max-depth=1 -- "$HOME"

--max-depth is GNU-specific; use the corresponding implementation’s manual page on other systems.

Troubleshooting

“No such file or directory”

Check the current directory, spelling, quoting, parent existence, and broken links:

pwd
printf '<%s>n' "$path"
ls -ld -- "$path"

“Permission denied”

Inspect every parent directory, not just the target:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
ls -ld -- / /path /path/to /path/to/target
id

On Linux, namei -l /path/to/target can show permissions along the path. Do not immediately add sudo; determine whether the problem is traversal, write permission, ownership, a read-only mount, an ACL, or mandatory access control.

“Directory not empty”

ls -la -- directory
find -- directory -mindepth 1 -maxdepth 1 -print

Hidden entries are a frequent cause. Decide whether each entry should be retained before using recursive removal.

Unexpected copy nesting

Inspect whether the destination already exists and verify the result with find -- destination -maxdepth 2 -print. The final operand’s type and the use of source versus source/. affect the layout.

Shell-script safety checklist

  • Quote path variables: "$target".
  • Use -- where supported.
  • Check the result of critical cd operations.
  • Preview recursive actions before applying them.
  • Do not parse ls output.
  • Handle unusual names with null-delimited processing.
  • Check mount points and filesystem boundaries before large recursive operations.
  • Validate deletion targets and refuse empty, root, or unexpectedly broad paths.

set -eu is a common baseline. Bash scripts often use set -euo pipefail, but pipefail is not POSIX syntax and shell error handling has exceptions, especially in conditionals, pipelines, and command substitutions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Cheat sheet

pwd                         # current directory
cd -- "$dir"               # change directory
ls -la                      # include hidden entries
ls -ld -- "$dir"           # inspect the directory entry
mkdir -p -- "$dir"         # create parents as needed
cp -a -- src dest           # copy with broad attribute preservation
mv -i -- old new            # inspect before overwriting
rmdir -- empty              # remove only an empty directory
find . -type d -print       # find directories
du -sh -- "$dir"           # tree usage estimate
df -h -- "$dir"            # filesystem capacity
chmod 750 -- "$dir"        # set directory permissions
chown user:group -- "$dir" # change ownership

When behavior matters, read the local documentation with man command, command --help where supported, or the relevant system manual. The safest directory command is the one whose target, scope, and effects you have verified first.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.