Skip to main content

How to Navigate the Linux Filesystem Like a Pro

Navigate the Linux filesystem safely with practical commands for paths, symlinks, permissions, file discovery, verification, and copying.

i
it.you Editorial Team
October 16, 2026 6 min read
How this article was made: An AI-assisted draft was fact-checked, its cited sources were opened, its examples were reviewed, and the published version was edited under the responsibility of it.you Editorial Team. Read our editorial process.
Linux terminal beside a filesystem tree showing directories, files, permissions, and a symbolic link

Navigate Linux safely by anchoring every operation to a known directory, resolving links, quoting paths, previewing targets, and verifying each copy or move.

Build the right filesystem mental model

Linux presents files, directories, devices, and mounted storage beneath one root directory, written as /. An absolute path starts there, while a relative path starts in the process’s current working directory. The kernel resolves each component from left to right; . means the current directory and .. means its parent. This behavior is documented in Linux path_resolution(7).

Do not confuse / with /root, which is normally the root user’s home directory. Common locations include /etc for host-specific configuration, /home for user directories, /var/log for logs, /tmp for temporary files, /usr for applications and shared data, and /srv for service data. These conventions are defined by the Filesystem Hierarchy Standard, although distributions and container images may omit or reorganize optional directories.

Before navigating, establish where you are with pwd. Use pwd -P when you need the physical path with symbolic links resolved. List entries with ls -la because plain ls omits names beginning with a dot. The Linux Commands Reference is useful when you need to confirm a command or option before applying it to real data.

Choose paths deliberately

  • Absolute path: /home/alex/project/config.ini identifies the same location regardless of the current directory.
  • Relative path: project/config.ini depends on the current directory and is convenient only when that context is known.
  • Home-relative path: ~/project is expanded by an interactive shell, but a quoted string such as "~/project" is not. In scripts, prefer "$HOME/project".
  • Symbolic link: A path may redirect to another path, potentially on another filesystem. Inspect it with readlink and resolve it with realpath -e.

Quote every variable that contains a path: use cd -- "$directory", not cd $directory. Quoting prevents spaces and wildcard characters from being split or expanded. The -- marker tells many GNU utilities that subsequent arguments are operands, so a filename such as -archive is not mistaken for an option.

Worked scenario: inspect and preserve an application log

Suppose an application uses a current symbolic link to select its active release. You need to locate that release, inspect its files without exposing a secret, and preserve its log in a private incident directory. The following lab reproduces that situation without requiring root access.

Create the sample filesystem

First confirm that the proposed lab path is unused. A successful test produces no output. If the second command prints already exists, choose another name; do not delete an existing directory merely to run the example.

lab="$HOME/fs-lab"
test ! -e "$lab" || printf '%s\n' 'already exists'
install -d -m 700 "$lab/releases/2026-10-16/logs"
printf '%s\n' 'APP_MODE=production' 'DB_PASSWORD=example-only' \
  > "$lab/releases/2026-10-16/.env"
printf '%s\n' \
  '2026-10-16T09:41:22Z WARN cache backend timeout' \
  '2026-10-16T09:41:23Z INFO request served status=200' \
  > "$lab/releases/2026-10-16/logs/app.log"
chmod 600 "$lab/releases/2026-10-16/.env"
chmod 640 "$lab/releases/2026-10-16/logs/app.log"
ln -s "releases/2026-10-16" "$lab/current"
cd -- "$lab"

Orient yourself and resolve the link

pwd -P
readlink -- current
realpath -e -- current

For a sample user named Alex, the expected output is:

/home/alex/fs-lab
releases/2026-10-16
/home/alex/fs-lab/releases/2026-10-16

readlink shows the link’s stored value, while realpath -e produces a canonical absolute path and requires every component to exist. GNU realpath removes ., .., and symbolic-link components, as described in the GNU Coreutils manual.

Apply a decision boundary before reading

Resolve the target once and confirm that it remains beneath the expected releases directory. Stop if the result points elsewhere:

target=$(realpath -e -- current) || exit 1
case "$target" in
  "$lab"/releases/*) printf 'approved target: %s\n' "$target" ;;
  *) printf 'refusing unexpected target: %s\n' "$target" >&2; exit 1 ;;
esac

The expected result is approved target: /home/alex/fs-lab/releases/2026-10-16. Now inventory names and permissions without printing file contents:

find "$target" -maxdepth 2 -type f -printf '%M %P\n' | sort

The expected output is:

-rw------- .env
-rw-r----- logs/app.log

The hidden .env file contains a credential-like value, so do not display or copy it. Only the log is required. The log’s status=200 indicates the recorded HTTP request succeeded; the HTTP Status Code Reference can help interpret other codes found during an investigation.

Copy privately and verify

incident="$HOME/incident-2026-10-16"
install -d -m 700 "$incident"
cp --preserve=timestamps -- "$target/logs/app.log" "$incident/"
chmod 600 "$incident/app.log"
sha256sum "$target/logs/app.log" "$incident/app.log"
cmp -s -- "$target/logs/app.log" "$incident/app.log" \
  && printf '%s\n' 'verified: files are identical'

Both hashes should be identical. With the exact sample data, the expected result is:

b83de267290a124312ca301ad2b39774d7346578970f366a7294b4e8cc8a9843  /home/alex/fs-lab/releases/2026-10-16/logs/app.log
b83de267290a124312ca301ad2b39774d7346578970f366a7294b4e8cc8a9843  /home/alex/incident-2026-10-16/app.log
verified: files are identical

The hash confirms matching content, while cmp supplies an independent byte-for-byte check. Ownership or timestamp differences require separate inspection with stat. Keep incident material private, minimize what you retain, and use an approved encrypted transfer method if it must leave the host.

Failure modes and safer alternatives

  • Broken or redirected links: A plain cd current may fail because the link target vanished, or it may enter an unexpected location after a deployment change. Use realpath -e and enforce an allowed path boundary before acting.
  • Permission denied: Directory execute permission controls traversal, even when a file itself is readable. Inspect the directory chain with ls -ld and confirm your identity with id. Do not reach automatically for sudo; elevated access can expose private data or turn a path mistake into system-wide damage.
  • Spaces, wildcards, or leading dashes: Unquoted paths can become multiple arguments, and filenames beginning with - can become options. Quote expansions and use --. For automated processing of arbitrary filenames, use null-delimited interfaces such as find ... -print0 with a compatible consumer.
  • Cross-filesystem moves: A same-filesystem mv is ordinarily a rename, but GNU mv may copy and then remove the source when the destination is on another filesystem. That fallback is not one indivisible rename, so verify free space and copied data before relying on it for important material. See the GNU mv documentation.
  • Changing targets during privileged work: Another process can replace a link between inspection and use. The shell procedure is suitable for a private lab or trusted tree, not an attacker-controlled directory. Security-sensitive software should use descriptor-based system calls such as openat2 with appropriate resolution restrictions.
  • Destructive cleanup: rm does not provide a normal undo operation. Preview exact targets, avoid broad recursive commands, and move uncertain material into a restricted quarantine directory when retention policy permits.

Reusable navigation checklist

  1. Identify yourself: Run id and avoid unnecessary privilege.
  2. Anchor your location: Run pwd -P before using relative paths.
  3. Inventory safely: Use ls -la, find, or stat before reading or changing content.
  4. Resolve indirection: Check symbolic links with readlink and realpath -e.
  5. Set a boundary: Confirm that the resolved target is inside the directory you intended.
  6. Protect arguments: Quote path expansions and use -- where supported.
  7. Minimize exposure: Do not print secret files or paste unredacted logs into tickets, chats, or public terminals.
  8. Prefer reversible actions: Copy first or quarantine uncertain files instead of deleting them.
  9. Verify the outcome: Re-list paths and use cmp, a checksum, or stat according to what must be preserved.

For related command and troubleshooting material, keep the Reference collection nearby, but verify distribution-specific behavior with the local manual page before operating on production data.

Sources and further reading

Related Tools

Searchable reference for common Linux commands wit…
Build and understand cron expressions with a visua…