How to Check for Root-Owned File Existence Using Sudo in Linux Shell Scripting


2 views

When writing shell scripts, you'll often need to verify file existence before operations. The standard test [ -f /path/to/file ] fails when:

  • The file requires root privileges to access
  • Your script runs as a regular user
  • The target file has strict permissions (e.g., 600)

The naive attempt sudo [ -f /path/to/file ] doesn't work because:

# This fails because:
# 1. '[' is a shell builtin, not an executable
# 2. Sudo expects a command binary
# 3. The test syntax gets parsed before sudo executes

Here are three reliable methods to check root-owned files:

Method 1: Sudo with Test Command

sudo test -f "/path/to/file" && echo "Exists" || echo "Missing"

Key points:

  • test is an actual executable (/usr/bin/test)
  • Works with all test operators (-f, -d, -x, etc.)
  • Returns proper exit codes for scripting

Method 2: Sudo with Bash Subshell

sudo bash -c '[[ -f "/path/to/file" ]]'

Advantages:

  • Uses bash's superior [[ ]] test syntax
  • Allows pattern matching and regex tests
  • Better handling of spaces in paths

Method 3: Sudo Combined with Stat

sudo stat "/path/to/file" >/dev/null 2>&1

When to use:

  • When you need additional file metadata
  • For more verbose error reporting
  • Cross-platform compatibility

Here's a complete script demonstrating privileged file checks:

#!/bin/bash

TARGET_FILE="/etc/securetty"

# Method 1 - Using test
if sudo test -f "$TARGET_FILE"; then
    echo "Method 1: File exists (test)"
else
    echo "Method 1: File missing"
fi

# Method 2 - Bash subshell
if sudo bash -c '[[ -f "$0" ]]' "$TARGET_FILE"; then
    echo "Method 2: File exists (bash)"
fi

# Method 3 - Error suppression
sudo stat "$TARGET_FILE" >/dev/null 2>&1
case $? in
    0) echo "Method 3: File exists (stat)";;
    *) echo "Method 3: File missing";;
esac
  • Quoting: Always quote paths containing spaces
  • Variables: Pass variables carefully in subshell methods
  • Performance: stat is heavier than test
  • Security: Validate paths before sudo execution

For complex conditional checks requiring root:

sudo bash -c '
    [[ -f "/etc/app/config" ]] && 
    grep -q "feature_flag" "/etc/app/config" &&
    [[ $(stat -c "%u" "/etc/app/config") -eq 0 ]]
' && echo "All conditions met"

When working as a regular user on Linux systems, you'll often encounter permission issues when trying to check system files owned by root. The naive approach of prefixing standard file test operators with sudo fails because:

sudo [ -f /path/to/file ]  # This doesn't work

The square bracket syntax is actually a shell builtin (or external test command), and sudo expects a complete command to execute. The shell processes the brackets before sudo even runs, leading to permission errors.

Here are several robust methods to check file existence with elevated privileges:

Method 1: Using sudo with test

sudo test -f /path/to/file && echo "Exists" || echo "Doesn't exist"

Method 2: Wrapping in a Shell

sudo sh -c '[ -f /path/to/file ] && echo "Exists" || echo "Missing"'

Method 3: Bash-specific Approach

sudo bash -c '[[ -f /path/to/file ]] && echo "Present" || echo "Absent"'

Let's examine some real-world scenarios:

Checking Configuration Files

# Check for MySQL config
sudo test -f /etc/mysql/my.cnf && echo "MySQL configured" || echo "No MySQL config"

Verifying Installation Files

# Verify Docker installation
if sudo test -f /usr/bin/docker; then
    echo "Docker is installed"
else
    echo "Docker not found"
fi

For scripting purposes, you might want to store the result:

# Store result in variable
if sudo test -f /var/log/syslog; then
    LOG_EXISTS=true
else
    LOG_EXISTS=false
fi
  • Forgetting that wildcards are expanded by the original shell, not the sudo shell
  • Assuming environment variables will be available in the sudo context
  • Neglecting to handle spaces in file paths properly

When using sudo for file checks:

  • Always use absolute paths to prevent path hijacking
  • Consider whether the check truly requires root privileges
  • Avoid exposing sensitive file information in output