Introduction to pwd
The pwd command (Print Working Directory) is one of the most fundamental and frequently used commands in Unix/Linux systems. It displays the full path of the current directory you're working in, helping you navigate and understand your position in the filesystem hierarchy.
Key Concepts
- Absolute Path: The complete path from the root directory (/) to your current location
- Working Directory: The directory you're currently "in" when executing commands
- Filesystem Navigation: Essential for understanding where you are in the directory structure
1. Basic Usage
Simple pwd Command
# Most basic usage - prints current directory pwd # Example output: # /home/username/Documents/projects # With no options, pwd shows the logical path (including symlinks) cd /tmp ln -s /home/username/Documents mydocs cd mydocs pwd # Output: /tmp/mydocs (follows the symlink)
Common Use Cases
# Check current directory before operations echo "Current directory: $(pwd)" ls -la # Store current directory in a variable CURRENT_DIR=$(pwd) echo "Working in: $CURRENT_DIR" # Return to previous directory cd /some/other/directory # Do some work... cd "$CURRENT_DIR" # Use in scripts for relative paths SCRIPT_DIR=$(pwd) cd /another/location # Do something cd "$SCRIPT_DIR"
2. Command Options
-L (Logical) Option
# -L shows logical path (follows symlinks) - This is the default pwd -L # Example with symlinks mkdir -p /tmp/real/path ln -s /tmp/real/path /tmp/symlink cd /tmp/symlink pwd -L # Output: /tmp/symlink pwd # Output: /tmp/symlink (same as -L by default)
-P (Physical) Option
# -P shows physical path (resolves all symlinks) pwd -P # Using the same symlink example cd /tmp/symlink pwd -P # Output: /tmp/real/path (resolves the symlink) # Compare both options echo "Logical: $(pwd -L)" echo "Physical: $(pwd -P)" # When both options are used, -P takes precedence pwd -L -P # Shows physical path
Option Comparison Table
| Option | Name | Behavior | Use Case |
|---|---|---|---|
| (none) | Default | Shows logical path | General navigation |
-L | Logical | Shows path with symlinks | When you want to see the symlink path |
-P | Physical | Resolves all symlinks | When you need the real filesystem path |
3. Practical Examples
Script Usage
#!/bin/bash # Example script demonstrating pwd usage SCRIPT_DIR=$(pwd) echo "Script running from: $SCRIPT_DIR" # Function to ensure we're in the right directory ensure_correct_directory() { local required_dir="/home/user/projects" local current_dir=$(pwd) if [ "$current_dir" != "$required_dir" ]; then echo "Error: Must be run from $required_dir" echo "Current directory: $current_dir" exit 1 fi } # Function to show directory structure show_directory_info() { echo "=== Directory Information ===" echo "Current: $(pwd)" echo "Parent: $(dirname $(pwd))" echo "Name: $(basename $(pwd))" echo "Physical: $(pwd -P)" echo "============================" } # Call the function show_directory_info Path Manipulation
#!/bin/bash # Using pwd with other commands CURRENT_PATH=$(pwd) # Extract parts of the path echo "Full path: $CURRENT_PATH" echo "Parent directory: $(dirname "$CURRENT_PATH")" echo "Current directory name: $(basename "$CURRENT_PATH")" # Build relative paths CONFIG_FILE="$(pwd)/config/settings.conf" DATA_DIR="$(pwd)/data/" echo "Config file: $CONFIG_FILE" echo "Data directory: $DATA_DIR" # Check if path contains specific substring if [[ $(pwd) == *"/projects/"* ]]; then echo "You're in a projects directory" fi
Navigation Helpers
#!/bin/bash # Create helper functions for navigation goto_project() { cd "$HOME/projects" echo "Now in: $(pwd)" } # Save current location and return save_and_cd() { local saved_location=$(pwd) cd "$1" || return 1 echo "Moved to: $(pwd)" echo "Saved location: $saved_location" } # Return to saved location go_back() { cd "$SAVED_LOCATION" echo "Back to: $(pwd)" } # Usage example save_and_cd /tmp # Do work in /tmp go_back 4. Integration with Other Commands
With find command
# Find files relative to current directory find "$(pwd)" -name "*.txt" -type f # Search in current directory and subdirectories find . -name "*.log" -exec echo "Found in $(pwd)/{}" \; # Find and process files with full paths find "$(pwd)" -type f -mtime -7 | while read -r file; do echo "Modified within 7 days: $file" done With ls and stat
# Detailed directory listing with path ls -la "$(pwd)" # Get filesystem information for current directory df -h "$(pwd)" # Get inode information stat "$(pwd)" # List with custom format ls -la --time-style=long-iso "$(pwd)"
With tar and backup commands
# Create backup with full path preservation tar -czf backup.tar.gz -C "$(pwd)" . # Backup with relative paths tar -czf "$HOME/backups/$(basename $(pwd)).tar.gz" . # Create timestamped backup BACKUP_NAME="backup-$(date +%Y%m%d-%H%M%S)-$(basename $(pwd)).tar.gz" tar -czf "$HOME/backups/$BACKUP_NAME" -C "$(dirname $(pwd))" "$(basename $(pwd))"
5. Advanced Techniques
Using pwd in Subshells
# pwd in subshell doesn't affect parent (cd /tmp && echo "Subshell: $(pwd)") echo "Parent: $(pwd)" # Multiple commands in subshell ( cd /var/log echo "Checking logs in: $(pwd)" ls -la *.log ) echo "Back to: $(pwd)" # Using subshell for safe directory changes update_project() { ( cd /tmp/project || exit 1 echo "Updating in: $(pwd)" git pull make build ) echo "Back to main directory: $(pwd)" } With Process Substitution
# Compare directory listings diff <(ls -la "$(pwd)") <(ls -la /tmp) # Monitor directory changes while true; do clear echo "Monitoring: $(pwd)" ls -la sleep 2 done # Create temporary file with path info cat > /tmp/dir_info.txt << EOF Current directory: $(pwd) Contents: $(ls) Timestamp: $(date) EOF
Environment Variables and pwd
# PWD is an environment variable automatically set by the shell echo "PWD variable: $PWD" echo "OLDPWD variable: $OLDPWD" # Previous directory # These are equivalent echo "Current: $(pwd)" echo "Current: $PWD" # Return to previous directory cd "$OLDPWD" echo "Now in: $(pwd)" # Create useful aliases alias where='echo "You are in: $(pwd)"' alias up='cd .. && echo "Moved up to: $(pwd)"' alias back='cd "$OLDPWD" && echo "Back to: $(pwd)"'
6. Error Handling and Edge Cases
Handling Permission Issues
#!/bin/bash # Check if we can access the current directory if [ -r "$(pwd)" ]; then echo "Current directory is readable" else echo "Warning: Cannot read current directory" fi # Check write permissions if [ -w "$(pwd)" ]; then echo "Can write to current directory" else echo "Cannot write to current directory" fi # Function with error handling safe_pwd() { local dir if dir=$(pwd 2>/dev/null); then echo "$dir" return 0 else echo "Error: Cannot determine current directory" >&2 return 1 fi } # Usage if current_dir=$(safe_pwd); then echo "Working in: $current_dir" else exit 1 fi Dealing with Deleted Directories
#!/bin/bash # Create and delete directory to demonstrate mkdir /tmp/testdir cd /tmp/testdir rm -rf /tmp/testdir # pwd still shows the old path but with a warning pwd # Output: /tmp/testdir (but directory no longer exists) # Check if current directory still exists check_directory() { if [ ! -d "$(pwd)" ]; then echo "Warning: Current directory no longer exists!" echo "You are in: $(pwd)" echo "Consider: cd /some/valid/path" return 1 fi return 0 } # Use in script if ! check_directory; then cd /tmp echo "Moved to safe directory: $(pwd)" fi 7. Performance Considerations
Measuring pwd Performance
#!/bin/bash # Time pwd execution time pwd # Compare with PWD variable time echo "$PWD" # For performance-critical scripts, use $PWD instead of calling pwd for i in {1..1000}; do # Faster - uses shell variable CURRENT="$PWD" # Slower - forks a process # CURRENT=$(pwd) done # Benchmark function benchmark() { local iterations=10000 echo "Benchmarking pwd vs PWD variable..." time ( for ((i=0; i<iterations; i++)); do pwd > /dev/null done ) time ( for ((i=0; i<iterations; i++)); do echo "$PWD" > /dev/null done ) } # Run benchmark benchmark Caching and Optimization
#!/bin/bash # Cache current directory for repeated use CURRENT_DIR="" get_current_dir() { if [ -z "$CURRENT_DIR" ]; then CURRENT_DIR=$(pwd) fi echo "$CURRENT_DIR" } # Use cached value process_files() { local dir dir=$(get_current_dir) for file in "$dir"/*; do echo "Processing: $file" done } # Directory tracking with automatic updates cd() { builtin cd "$@" || return CURRENT_DIR=$(pwd) echo "Now in: $CURRENT_DIR" } 8. Integration with Other Tools
With Git
#!/bin/bash # Git-aware prompt git_branch() { git branch 2>/dev/null | grep '^*' | colrm 1 2 } # Show current directory with git info show_prompt() { local dir=$(pwd) local branch=$(git_branch) if [ -n "$branch" ]; then echo "$dir (git: $branch)" else echo "$dir" fi } # Git operations relative to current directory git_status() { echo "Checking git status in: $(pwd)" git status -s } # Find git root from current directory git_root() { local dir=$(pwd) while [ "$dir" != "/" ]; do if [ -d "$dir/.git" ]; then echo "$dir" return 0 fi dir=$(dirname "$dir") done return 1 } With Docker
#!/bin/bash # Mount current directory in Docker docker_run() { docker run -v "$(pwd):/workspace" -w /workspace "$@" } # Docker compose with relative paths docker_compose_up() { echo "Starting services from: $(pwd)" docker-compose -f "$(pwd)/docker-compose.yml" up -d } # Build Docker image with context from current directory docker_build_current() { local tag=${1:-latest} docker build -t "app:$tag" "$(pwd)" } With Make
#!/bin/bash # Makefile integration make_with_path() { make -C "$(pwd)" "$@" } # Check if Makefile exists in current directory check_makefile() { if [ -f "$(pwd)/Makefile" ]; then echo "Makefile found in: $(pwd)" return 0 else echo "No Makefile in: $(pwd)" return 1 fi } 9. Common Pitfalls and Solutions
Spaces in Path Names
#!/bin/bash # Create directory with spaces mkdir -p "/tmp/my projects/test" cd "/tmp/my projects/test" # WRONG: Unquoted pwd can cause issues PROJECT_DIR=$(pwd) # This is actually safe, but when using it: # ls $PROJECT_DIR # This would break with spaces # CORRECT: Always quote when using PROJECT_DIR="$(pwd)" ls "$PROJECT_DIR" # Works correctly # In scripts, always use quotes process_directory() { local dir dir="$(pwd)" # Safe operations for file in "$dir"/*; do echo "Found: $file" done } # Array handling with spaces files=("$(pwd)"/*.txt) for file in "${files[@]}"; do echo "Processing: $file" done Symbolic Link Traversal
#!/bin/bash # Create symlink maze mkdir -p /tmp/real/a/b/c ln -s /tmp/real /tmp/link cd /tmp/link/a/b/c # Function to show both logical and physical paths show_paths() { echo "Logical (with symlinks): $(pwd -L)" echo "Physical (resolved): $(pwd -P)" # Compare them if [ "$(pwd -L)" != "$(pwd -P)" ]; then echo "Path contains symlinks" fi } # Choose appropriate path based on need copy_config() { local source_file="$1" # Use physical path for actual file operations local real_path="$(pwd -P)/$source_file" # Use logical path for user display local display_path="$(pwd -L)/$source_file" echo "Copying from: $display_path" cp "$real_path" /destination/ } 10. Real-World Examples
Project Setup Script
#!/bin/bash # Comprehensive project setup script setup_project() { local project_name="$1" local base_dir base_dir="$(pwd)" echo "Setting up project '$project_name' in: $base_dir" # Create project structure mkdir -p "$base_dir/$project_name"/{src,tests,docs,config} # Create files with absolute paths cat > "$base_dir/$project_name/README.md" << EOF # $project_name Project created on $(date) Location: $base_dir/$project_name EOF # Create configuration with path info cat > "$base_dir/$project_name/config/settings.json" << EOF { "project_name": "$project_name", "project_path": "$base_dir/$project_name", "created_at": "$(date -Iseconds)" } EOF echo "Project structure created:" tree "$base_dir/$project_name" # Return project path echo "$base_dir/$project_name" } # Usage PROJECT_PATH=$(setup_project "myapp") cd "$PROJECT_PATH" Directory Watcher
#!/bin/bash # Monitor directory for changes watch_directory() { local watch_dir watch_dir="$(pwd)" local watch_interval=2 echo "Watching directory: $watch_dir" echo "Press Ctrl+C to stop" local last_files="" while true; do clear echo "=== Directory Watch: $(date) ===" echo "Path: $watch_dir" echo "Contents:" local current_files current_files=$(ls -la "$watch_dir") echo "$current_files" if [ -n "$last_files" ] && [ "$current_files" != "$last_files" ]; then echo "*** Directory changed! ***" # Could trigger actions here fi last_files="$current_files" sleep $watch_interval done } # Usage - cd to directory first, then run # cd /path/to/watch # watch_directory Build System Helper
#!/bin/bash # Smart build script that works from any directory build_project() { local script_dir script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" echo "Build script location: $script_dir" echo "Current working dir: $(pwd)" # If not in project root, try to find it if [ ! -f "$(pwd)/Cargo.toml" ] && [ ! -f "$(pwd)/Makefile" ]; then echo "Not in project root, searching..." local dir="$(pwd)" while [ "$dir" != "/" ]; do if [ -f "$dir/Cargo.toml" ] || [ -f "$dir/Makefile" ]; then echo "Found project root: $dir" cd "$dir" break fi dir=$(dirname "$dir") done fi # Now build based on project type if [ -f "Cargo.toml" ]; then echo "Building Rust project in: $(pwd)" cargo build --release elif [ -f "Makefile" ]; then echo "Building with make in: $(pwd)" make else echo "No build configuration found in: $(pwd)" return 1 fi } # Run build build_project 11. Cross-Platform Considerations
POSIX Compliance
#!/bin/bash # POSIX-compliant pwd usage get_current_directory() { # POSIX shell doesn't have -P or -L options # Use pwd without options for maximum compatibility pwd } # More portable version for scripts portable_pwd() { if command -v realpath >/dev/null 2>&1; then realpath "$(pwd)" elif command -v readlink >/dev/null 2>&1; then readlink -f "$(pwd)" 2>/dev/null || pwd else pwd fi } # Handle different OS behaviors detect_os() { case "$(uname -s)" in Linux*) echo "Linux" ;; Darwin*) echo "macOS" ;; CYGWIN*) echo "Cygwin" ;; MINGW*) echo "MinGW" ;; *) echo "Unknown" ;; esac } os_specific_pwd() { local os os=$(detect_os) case "$os" in "Linux") pwd -P # On Linux, often want physical path ;; "macOS") pwd -L # On macOS, logical path often preferred ;; *) pwd # Default ;; esac } 12. Advanced Scripting Patterns
Recursive Directory Operations
#!/bin/bash # Recursive operation starting from current directory process_recursive() { local dir="${1:-$(pwd)}" local depth="${2:-0}" local indent="$3" if [ -z "$indent" ]; then indent="" echo "Starting from: $dir" fi # Process current directory echo "${indent}📁 $dir" # Process files for file in "$dir"/*; do if [ -f "$file" ]; then echo "${indent} 📄 $(basename "$file")" elif [ -d "$file" ]; then # Recursively process subdirectories process_recursive "$file" $((depth + 1)) "${indent} " fi done } # Find and process directories with specific criteria find_and_process() { local search_dir="${1:-$(pwd)}" local pattern="$2" find "$search_dir" -type d -name "$pattern" | while read -r dir; do echo "Found directory: $dir" (cd "$dir" && echo "Processing in: $(pwd)" && ls -la) done } Path Validation and Sanitization
#!/bin/bash # Validate and sanitize paths validate_path() { local path="${1:-$(pwd)}" # Check if path exists if [ ! -e "$path" ]; then echo "Error: Path does not exist: $path" >&2 return 1 fi # Get absolute path local abs_path if ! abs_path=$(cd "$(dirname "$path")" && pwd)/$(basename "$path") 2>/dev/null; then echo "Error: Cannot resolve absolute path" >&2 return 1 fi # Remove redundant slashes and . components abs_path=$(echo "$abs_path" | sed 's#/\./#/#g; s#//*#/#g') echo "$abs_path" } # Safe directory change with validation safe_cd() { local target="$1" if [ -z "$target" ]; then cd "$HOME" || return 1 echo "Moved to home: $(pwd)" return 0 fi if [ ! -d "$target" ]; then echo "Error: Not a directory: $target" >&2 return 1 fi if [ ! -r "$target" ] || [ ! -x "$target" ]; then echo "Error: No permission to access: $target" >&2 return 1 fi cd "$target" || return 1 echo "Now in: $(pwd)" } 13. Performance Optimization Scripts
Directory Indexing
#!/bin/bash # Create quick directory index for faster navigation create_index() { local index_file="$HOME/.dir_index" local start_dir="${1:-$(pwd)}" echo "Creating directory index from: $start_dir" echo "# Directory Index - Created $(date)" > "$index_file" find "$start_dir" -type d 2>/dev/null | while read -r dir; do echo "$dir" >> "$index_file" done echo "Index created with $(wc -l < "$index_file") entries" } # Quick directory search quick_cd() { local search="$1" local index_file="$HOME/.dir_index" if [ ! -f "$index_file" ]; then echo "Index not found. Creating..." create_index "$HOME" fi local matches matches=$(grep -i "$search" "$index_file" | head -10) if [ -z "$matches" ]; then echo "No matches found" return 1 fi local count count=$(echo "$matches" | wc -l) if [ "$count" -eq 1 ]; then cd "$matches" || return 1 echo "Moved to: $(pwd)" else echo "Multiple matches:" echo "$matches" | nl -w2 -s': ' echo -n "Choose (1-$count): " read -r choice if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "$count" ]; then cd "$(echo "$matches" | sed -n "${choice}p")" || return 1 echo "Moved to: $(pwd)" fi fi } 14. Integration with Shell Configuration
Shell Prompt Enhancement
# Add to .bashrc or .zshrc for enhanced prompt # Custom prompt with path shortening shorten_path() { local path="$(pwd)" local home="$HOME" # Replace home with ~ path="${path/#$home/~}" # Shorten if too long if [ ${#path} -gt 30 ]; then echo "...${path: -25}" else echo "$path" fi } # Git branch in prompt git_branch() { git branch 2>/dev/null | grep '^*' | colrm 1 2 } # Enhanced PS1 PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]$(shorten_path)\[\033[00m\]$(git_branch)$ ' # Directory history pushd() { builtin pushd "$@" || return echo "Now in: $(pwd)" } popd() { builtin popd || return echo "Now in: $(pwd)" } # Directory stack display dirs() { builtin dirs -v } Navigation Shortcuts
# Add to .bashrc for quick navigation # Quick navigation functions cdl() { cd "$1" && ls -la } cdf() { cd "$(dirname "$1")" } mkcd() { mkdir -p "$1" && cd "$1" } # History-based navigation cdh() { local dir dir=$(fc -l 1 | grep ' cd ' | awk '{print $NF}' | fzf) [ -n "$dir" ] && cd "$dir" } # Project hopping goto() { local projects_dir="$HOME/projects" local dir if [ -z "$1" ]; then dir=$(find "$projects_dir" -maxdepth 3 -type d | fzf) else dir=$(find "$projects_dir" -maxdepth 3 -type d -name "*$1*" | head -1) fi if [ -n "$dir" ]; then cd "$dir" echo "Now in: $(pwd)" fi } 15. Testing and Debugging
Pwd Testing Framework
#!/bin/bash # Test pwd behavior in different scenarios test_pwd() { echo "=== pwd Test Suite ===" # Test 1: Basic functionality echo "Test 1: Basic pwd" local current current=$(pwd) echo " Current directory: $current" [ -n "$current" ] && echo " ✓ Basic test passed" || echo " ✗ Basic test failed" # Test 2: Directory change echo "Test 2: Directory change" local old_dir="$current" cd /tmp local new_dir=$(pwd) cd "$old_dir" [ "$new_dir" = "/tmp" ] && echo " ✓ Directory change test passed" || echo " ✗ Directory change test failed" # Test 3: Symlink handling echo "Test 3: Symlink handling" if [ -L "$current" ]; then local logical=$(pwd -L) local physical=$(pwd -P) [ "$logical" != "$physical" ] && echo " ✓ Symlink test passed" || echo " ✗ Symlink test failed" else echo " - Current directory not a symlink, skipping" fi # Test 4: Unreadable directory echo "Test 4: Permission handling" if [ -d "/root" ] 2>/dev/null; then (cd /root 2>/dev/null && pwd 2>/dev/null) [ $? -ne 0 ] && echo " ✓ Permission test passed" || echo " ✗ Permission test failed" else echo " - /root not accessible, skipping" fi } # Debug pwd issues debug_pwd() { echo "=== pwd Debug Information ===" echo "Command: $(which pwd)" echo "Version: $(pwd --version 2>&1 || echo 'No version info')" echo "Current directory:" ls -ld "$(pwd)" echo "Parent directory:" ls -ld "$(dirname $(pwd))" echo "Filesystem info:" df -h "$(pwd)" echo "Environment:" echo "PWD=$PWD" echo "OLDPWD=$OLDPWD" } Conclusion
The pwd command, while simple, is an essential tool for Unix/Linux navigation and scripting:
Key Takeaways
- Two modes: Logical (
-L) and Physical (-P) path resolution - Shell variable:
$PWDprovides faster access than callingpwd - Script usage: Always quote
$(pwd)to handle paths with spaces - Error handling: Check for directory existence and permissions
- Performance: Use
$PWDin loops and frequently accessed code - Integration: Essential for relative path construction and navigation
Best Practices
| Scenario | Recommendation |
|---|---|
| Interactive use | Use plain pwd or $PWD |
| Scripts with symlinks | Consider pwd -P for file operations |
| Performance-critical | Use $PWD variable |
| Cross-platform | Use POSIX-compliant pwd |
| With spaces in paths | Always quote "$(pwd)" |
Common Use Cases
- Navigation: Understanding your current location
- Scripting: Building relative and absolute paths
- Logging: Recording where operations occur
- Debugging: Tracking down path-related issues
- Automation: Ensuring scripts run from correct directories
The pwd command's simplicity belies its importance - it's a fundamental tool that every Unix/Linux user should master for efficient system navigation and scripting.
Complete Bash Exercises with Solutions
Practice Bash scripting with solved exercises to improve your command-line and scripting skills.
Link: https://macronepal.com/complete-bash-exercises-with-solutions/
Complete Guide to Bash Crontab Command
Learn how to schedule and automate tasks efficiently using the Bash crontab command.
Link: https://macronepal.com/complete-guide-to-bash-crontab-command-schedule-tasks/
Complete Guide to Bash Arrays
Understand how to create, manage, and use arrays in Bash scripting.
Link: https://macronepal.com/complete-guide-to-bash-arrays/
Bash Quiz: Test Your Knowledge
Test your Bash scripting knowledge with quizzes and practical questions.
Link: https://macronepal.com/bash-quiz-test-your-knowledge/
Complete Guide to Bash Functions
Learn how to write reusable Bash functions for cleaner and efficient scripts.
Link: https://macronepal.com/complete-guide-to-bash-functions/
Complete Guide to Bash Loops
Master loops in Bash for repetitive tasks and automation.
Link: https://macronepal.com/complete-guide-to-bash-loops/
Complete Guide to Bash If-Else Statements
Learn decision-making in Bash using conditional statements.
Link: https://macronepal.com/complete-guide-to-bash-ifelse-statements/
Complete Guide to Bash Operators
Explore arithmetic, logical, and comparison operators in Bash.
Link: https://macronepal.com/complete-guide-to-bash-operators/
Complete Guide to Bash Data Types
Understand variables and different data types used in Bash scripting.
Link: https://macronepal.com/complete-guide-to-bash-data-types/
Complete Guide to Bash Variables
Learn how to declare, assign, and use variables in Bash scripts.
Link: https://macronepal.com/complete-guide-to-bash-variables/
Complete Guide to Bash Scripting
A complete introduction to writing Bash scripts for automation.
Link: https://macronepal.com/complete-guide-to-bash-scripting/
Complete Guide to Basic Bash Syntax
Learn the fundamental syntax needed to write Bash commands and scripts.
Link: https://macronepal.com/complete-guide-to-basic-bash-syntax/
Complete Guide to Bash Chgrp Command
Learn how to change group ownership of files and directories.
Link: https://macronepal.com/complete-guide-to-bash-chgrp-command-change-group-ownership-2/
Complete Guide to Bash Chgrp Command (Alternate)
Another detailed explanation of Bash group ownership management.
Link: https://macronepal.com/complete-guide-to-bash-chgrp-command-change-group-ownership/
Complete Guide to Bash File Permissions and Ownership
Understand Linux file permissions and ownership management.
Link: https://macronepal.com/complete-guide-to-bash-file-permissions-and-ownership/
Complete Guide to Bash Chmod Command
Learn how to modify file permissions using chmod.
Link: https://macronepal.com/complete-guide-to-bash-chmod-command-change-file-permissions/
Complete Guide to Bash Chown Command
Change file ownership using the Bash chown command.
Link: https://macronepal.com/complete-guide-to-bash-chown-command-change-file-ownership/
Complete Guide to Bash SCP Command
Securely transfer files between systems using SCP.
Link: https://macronepal.com/complete-guide-to-bash-scp-command-secure-copy/
Complete Guide to Bash SSH Command
Learn secure remote access and server management using SSH.
Link: https://macronepal.com/complete-guide-to-bash-ssh-command/
Bash Wget Command Complete Guide
Download files from the internet using the wget command.
Link: https://macronepal.com/bash-wget-command-complete-guide-to-non-interactive-network-downloader/
