Skip to main content

How to Get File Permissions

3 min read
bash file permissions stat ls file security

Quick Answer: Get File Permissions in Bash

To get file permissions in Bash, use stat -c %a file.txt for numeric format (e.g., 644) or ls -l file.txt | awk '{print $1}' for symbolic format (e.g., -rw-r—r—). The stat command is most reliable and provides detailed information.

Quick Comparison: Permission Checking Methods

MethodFormatSpeedBest ForPortability
stat -c %aNumeric (755)FastScripts, automationLinux/Unix
ls -lSymbolic (-rwx)FastHuman readingAll systems
Test operatorsBooleanFastestSimple checksAll Bash
find -permNumeric/octalMediumBulk searchesAll systems
getfaclExtended ACLMediumAdvanced permissionsSome systems

Bottom line: Use stat -c %a for numeric permissions in scripts; use test operators for simple access checks.


Getting File Permissions

Understanding how to read and extract file permissions is essential for checking security settings and validating file states. You can use ls, stat, or other commands to inspect permissions.

The stat command is the most reliable way to extract permissions for scripting. It provides consistent, predictable output:

#!/bin/bash

file="myfile.txt"

# Get permissions in octal (numeric)
perms=$(stat -c %a "$file")
echo "Numeric permissions: $perms"
# Output: 644

Numeric permissions are easier to work with in scripts. The format 755 means: owner=7 (rwx), group=5 (r-x), other=5 (r-x).

When to Use stat

Use stat when:

  • You need to extract permissions for script automation
  • You want reliable, consistent output
  • You’re checking permission bits in conditions
  • You need owner/group information alongside permissions

Method 2: Reading Permissions with ls

The most common way to see permissions visually:

$ ls -l file.txt
-rw-r--r-- 1 user group 1234 Feb 21 14:30 file.txt

# Permission breakdown: -rw-r--r--
# - = regular file
# rw- = user (owner) permissions
# r-- = group permissions
# r-- = other permissions

Extracting Permissions from ls Output in Scripts

Get permissions numerically or symbolically:

#!/bin/bash

file="myfile.txt"

# Get permissions in octal (numeric)
perms=$(stat -c %a "$file")
echo "Numeric permissions: $perms"
# Output: 644

# Get permissions with ls
perms=$(ls -l "$file" | awk '{print $1}')
echo "Symbolic permissions: $perms"
# Output: -rw-r--r--

Method 3: Using stat for Detailed Information

The stat command provides comprehensive permission information in one command:

#!/bin/bash

file="document.txt"

# Get all file information
stat "$file"

# Get specific format
echo "Access rights: $(stat -c "%a" "$file")"
echo "Owner/Group: $(stat -c "%U:%G" "$file")"

# Get in verbose format
stat -c "File: %n
Access: %a (%A)
Owner: %U (%u)
Group: %G (%g)" "$file"

This approach is powerful because you can format the output exactly as you need. The stat command has many format specifiers for different permission and ownership details.

Method 4: Test Operators for Simple Checks

For quick checks in conditions, use Bash test operators which are fastest:

#!/bin/bash

file="myfile.txt"

# Check if readable
if [ -r "$file" ]; then
  echo "File is readable"
fi

# Check if writable
if [ -w "$file" ]; then
  echo "File is writable"
fi

# Check if executable
if [ -x "$file" ]; then
  echo "File is executable"
fi

# Check if owned by current user
if [ -O "$file" ]; then
  echo "You own this file"
fi

When to Use Test Operators

Use these when:

  • You just need a yes/no answer about permissions
  • You’re doing simple permission checks in conditions
  • You want the fastest performance
  • Portability is important (works on all Bash versions)

Method 5: Converting Between Permission Formats

Understand the numeric permission breakdown:

#!/bin/bash

# Numeric explanation
explain_numeric() {
  local perms="$1"

  # Break down 755:
  # 7 = user (4+2+1 = read+write+execute)
  # 5 = group (4+1 = read+execute)
  # 5 = other (4+1 = read+execute)

  local user=$((perms / 100))
  local group=$(((perms % 100) / 10))
  local other=$((perms % 10))

  echo "User: $user, Group: $group, Other: $other"
}

explain_numeric 755
# Output: User: 7, Group: 5, Other: 5

Real-World Example: Permission Audit

#!/bin/bash

audit_permissions() {
  local dir="$1"

  echo "Permission Audit for: $dir"
  echo "============================================"

  for file in "$dir"/*; do
    [ -e "$file" ] || continue

    perms=$(stat -c %a "$file")
    owner=$(stat -c %U "$file")
    group=$(stat -c %G "$file")
    type=$(stat -c %F "$file")

    printf "%-40s %s:%s %s (%s)\n" \
      "$(basename "$file")" \
      "$owner" "$group" "$perms" "$type"
  done
}

audit_permissions "/tmp"

Finding Files by Permission

#!/bin/bash

# Find world-writable files (security risk!)
find_world_writable() {
  local dir="$1"
  echo "World-writable files in $dir:"
  find "$dir" -perm -002 -type f 2>/dev/null
}

# Find files with specific permission
find_permission() {
  local dir="$1"
  local perm="$2"
  echo "Files with permission $perm:"
  find "$dir" -perm "$perm" 2>/dev/null
}

find_world_writable "/tmp"
find_permission "/home" "0755"

Checking Specific Permission Bits

#!/bin/bash

# Check if file is world-readable
is_world_readable() {
  local file="$1"
  local perms=$(stat -c %a "$file")
  [ $((perms % 10)) -ge 4 ] && return 0 || return 1
}

# Check if file is group-writable
is_group_writable() {
  local file="$1"
  local perms=$(stat -c %a "$file")
  local group_perms=$(((perms % 100) / 10))
  [ $((group_perms % 2)) -eq 1 ] && return 0 || return 1
}

if is_world_readable "/tmp/file.txt"; then
  echo "File is world-readable"
fi

Practical Example: Security Check

#!/bin/bash

check_file_security() {
  local file="$1"

  echo "Security check for: $file"

  # Get permissions
  perms=$(stat -c %a "$file")
  owner=$(stat -c %U "$file")

  # Check for security issues
  if [ $((perms % 10)) -ge 2 ]; then
    echo "⚠️  WARNING: File is world-writable (permissions: $perms)"
  fi

  if [ $((((perms % 100) / 10) % 2)) -eq 1 ]; then
    echo "⚠️  WARNING: File is group-writable (permissions: $perms)"
  fi

  if [[ "$owner" != "$USER" ]]; then
    echo "ℹ️  File is owned by: $owner"
  fi

  # Check if it's private (600/700)
  if [ "$perms" = "600" ] || [ "$perms" = "700" ]; then
    echo "✓ File has private permissions"
  fi
}

check_file_security "/home/user/.ssh/id_rsa"

Getting ACL Information

For extended permissions (ACL):

#!/bin/bash

# View extended ACLs if present
if command -v getfacl &>/dev/null; then
  getfacl file.txt
else
  echo "ACL tools not available"
fi

Important Notes

  • - at start means regular file, d means directory
  • Permission groups: user (owner), group, others
  • Each permission: r (read=4), w (write=2), x (execute=1)
  • stat with -c %a gives numeric permissions
  • ls -l gives symbolic permissions and file type

Quick Reference

# Get numeric permissions
stat -c %a file.txt

# Get full details
stat file.txt

# Get symbolic permissions
ls -l file.txt | awk '{print $1}'

# Check if readable
[ -r file.txt ] && echo "Readable"

# Check if writable
[ -w file.txt ] && echo "Writable"

# Check if executable
[ -x file.txt ] && echo "Executable"

# Find world-writable files
find . -perm -002 -type f

# Get owner and group
stat -c "%U:%G" file.txt

Summary

Use stat -c %a to get numeric permissions, ls -l for symbolic, and the -r, -w, -x test operators for simple checks. Understanding permission formats helps you audit security and troubleshoot access issues.