2.1. Advanced Navigation#
Now that you understand the basics of moving around the filesystem, let’s explore more sophisticated path concepts. You’ll learn about symlinks, the PATH environment variable, and powerful search tools that help you find anything on your system.
2.1.1. Understanding the PATH Variable#
When you type a command, the shell doesn’t search the entire filesystem. Instead, it searches directories listed in the PATH environment variable.
2.1.1.1. Viewing Your PATH#
$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
# Or display it more nicely
$ echo $PATH | tr ':' '\n'
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
Each directory is separated by a colon (:). The shell searches them in order, left to right.
echo $PATH
/home/tychen/bash/.venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
echo $PATH | tr ':' '\n'
/home/tychen/bash/.venv/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
2.1.1.2. Finding Where a Program Is Located#
# See the full path of a command
$ which python3
/usr/bin/python3
# Show all matching programs in PATH
$ which -a python
/usr/bin/python
/usr/local/bin/python
# Check if a command exists without running it
$ command -v ls
ls is aliased to `ls -G'
2.1.1.3. Adding to Your PATH#
To add a directory to your PATH, modify your shell configuration:
# Add current directory temporarily
$ export PATH="$PATH:."
# Add custom directory permanently (add to ~/.bashrc)
$ echo 'export PATH="$PATH:$HOME/bin"' >> ~/.bashrc
$ source ~/.bashrc
2.1.1.4. PATH Security Considerations#
Never put the current directory (.) at the beginning of PATH:
# Bad! Security risk
$ export PATH=".:$PATH"
# Good - search home/bin first, then system paths
$ export PATH="$HOME/bin:$PATH"
This prevents running unintended programs if someone creates a malicious script with a common name.
2.1.2. Symbolic Links (Symlinks)#
Symbolic links are shortcuts to files or directories. They’re different from the original—changing a symlink doesn’t affect the original, but they point to the same content.
2.1.2.1. Creating Symlinks#
# Create a symlink to a file
$ ln -s /usr/bin/python3 ~/bin/python
# Create a symlink to a directory
$ ln -s ~/Documents/Projects ~/projects
# Verify the symlink
$ ls -l ~/bin/python
lrwxr-xr-x 1 user staff 18 Dec 19 10:00 python -> /usr/bin/python3
The l at the beginning indicates it’s a link, and the -> shows where it points.
2.1.2.2. Following Symlinks with cd#
# Navigate using symlink
$ cd ~/projects
# See where you really are
$ pwd
/Users/user/Documents/Projects
# Or see the symlink path with -P
$ pwd -P
/Users/user/Documents/Projects
2.1.2.3. Removing Symlinks#
# Delete the symlink (not the target!)
$ rm ~/projects
# Verify it's gone
$ ls ~/
2.1.2.4. Real-World Example: Multiple Python Versions#
# System might have python3.9, 3.10, 3.11 installed
$ ls /usr/bin/python*
/usr/bin/python3.9
/usr/bin/python3.10
/usr/bin/python3.11
# Create symlinks for easy access
$ ln -s /usr/bin/python3.11 /usr/local/bin/python3
$ ln -s /usr/bin/python3.11 /usr/local/bin/python
# Now 'python' and 'python3' both point to 3.11
$ python --version
Python 3.11.5
2.1.3. Finding Files: locate vs find#
Two main tools for searching: locate (fast, indexed) and find (comprehensive, flexible).
2.1.3.1. locate — Fast Database Searches#
locate searches a pre-built database (much faster but less current):
# Find all files named "python"
$ locate python
# Case-insensitive search
$ locate -i PYTHON
# Search by pattern
$ locate "*.conf"
# Update the database (usually done automatically nightly)
$ updatedb # May require sudo
Pros: Very fast Cons: Only finds what’s in the database; database updates nightly
2.1.3.2. find — Powerful, Comprehensive Searches#
find searches the live filesystem (slower but more thorough):
# Find files named exactly "test.txt"
$ find ~ -name "test.txt"
# Case-insensitive name search
$ find ~ -iname "test.txt"
# Find files modified in last 7 days
$ find ~ -mtime -7
# Find large files (over 100MB)
$ find ~ -size +100M
# Find directories only
$ find ~ -type d
# Find executable files
$ find ~ -type f -executable
# Combine conditions (AND)
$ find ~ -type f -name "*.py" -mtime -30
# Find files owned by a specific user
$ find ~ -user username
# Execute a command on found files
$ find ~ -name "*.tmp" -delete
$ find ~ -name "*.txt" -exec cat {} \;
2.1.3.3. Combining Commands with find#
# Find all Python files and count lines
$ find ~ -name "*.py" -exec wc -l {} +
# Find and copy files
$ find ~ -name "*.bak" -exec cp {} ~/backup/ \;
# Find and move files
$ find ~ -name "*temp*" -exec mv {} /tmp/ \;