How to Programmatically Identify Filesystem Type and Mount Point for a Given File Path in Unix/Linux


2 views

When working with filesystem-specific features (like extended attributes, ACLs, or compression), we often need to determine the underlying filesystem type and mount point for a given file path. While the mount command provides this information, parsing its output in scripts can be brittle and platform-dependent.

Here's a more reliable approach that combines several Unix utilities:

#!/bin/bash

filepath="/path/to/your/file"

# Get filesystem device
fs_device=$(df --output=source "$filepath" | tail -n1)

# Get mount point
mount_point=$(df --output=target "$filepath" | tail -n1)

# Get filesystem type
fs_type=$(stat -f -c %T "$filepath")

echo "File: $filepath"
echo "Filesystem device: $fs_device"
echo "Mount point: $mount_point"
echo "Filesystem type: $fs_type"

For more robust handling, consider these scenarios:

# Cross-platform version (works on BSD/macOS too)
if [[ "$(uname)" == "Linux" ]]; then
    fs_type=$(stat -f -c %T "$filepath")
else
    # BSD/macOS version
    fs_type=$(stat -f %T "$filepath")
fi

# Handle symlinks properly
real_path=$(readlink -f "$filepath")
fs_device=$(df --output=source "$real_path" | tail -n1)

On modern Linux systems, findmnt offers a cleaner interface:

# Get comprehensive filesystem info
findmnt -T "$filepath" -o SOURCE,TARGET,FSTYPE,OPTIONS

# JSON output for parsing
findmnt -J -T "$filepath"

Here's how you might use this in a script handling extended attributes:

check_xattr_support() {
    local file=$1
    local fs_type=$(stat -f -c %T "$file")
    
    case "$fs_type" in
        "ext2"|"ext3"|"ext4"|"xfs"|"btrfs"|"reiserfs"|"jfs")
            return 0
            ;;
        *)
            echo "Unsupported filesystem: $fs_type" >&2
            return 1
            ;;
    esac
}

For scripts processing many files, minimize filesystem calls:

# Cache filesystem info for parent directory
dir_fs=$(stat -f -c %T "/path/to/parent")
file_fs=$(stat -f -c %T "/path/to/parent/file")

if [[ "$dir_fs" != "$file_fs" ]]; then
    echo "Warning: File crossed filesystem boundary" >&2
fi

When working with files in Unix-like systems, you might need to determine which filesystem a file resides on, its mount point, and its filesystem type. This is particularly useful for scripts that interact with filesystem-specific features like extended attributes (xattr), disk quotas, or encryption.

The most straightforward method is to parse the output of the mount command:


mount | grep '/dev'

However, this approach has several drawbacks:

  • Output format varies across Unix variants
  • Requires complex parsing for reliable results
  • Doesn't directly map a file path to its filesystem

A more robust approach combines df and stat commands:


# Get the mount point
MOUNTPOINT=$(df --output=target "$FILE" | tail -n 1)

# Get the filesystem type
FSTYPE=$(stat -f -c %T "$FILE")

Different Unix variants may require adjustments:

Linux Systems


# Modern Linux with GNU coreutils
FSTYPE=$(stat -f -c %T "$FILE")

# Alternative using findmnt
MOUNTPOINT=$(findmnt -n -o TARGET --target "$FILE")

macOS (Darwin)


# macOS specific implementation
MOUNTPOINT=$(df "$FILE" | tail -1 | awk '{print $NF}')
FSTYPE=$(diskutil info "$MOUNTPOINT" | grep "Type (Bundle):" | awk '{print $3}')

Here's a portable function that works across most Unix-like systems:


get_filesystem_info() {
    local file="$1"
    if [ ! -e "$file" ]; then
        echo "File does not exist" >&2
        return 1
    fi
    
    # Get mount point
    if command -v findmnt >/dev/null; then
        mountpoint=$(findmnt -n -o TARGET --target "$file")
    else
        mountpoint=$(df --output=target "$file" | tail -n 1)
    fi
    
    # Get filesystem type
    if [ "$(uname)" = "Darwin" ]; then
        fstype=$(diskutil info "$mountpoint" | grep "Type (Bundle):" | awk '{print $3}')
    else
        fstype=$(stat -f -c %T "$file" 2>/dev/null || df --output=fstype "$file" | tail -n 1)
    fi
    
    echo "Mount Point: $mountpoint"
    echo "Filesystem Type: $fstype"
}

Consider these special scenarios:

  • Bind mounts may show multiple mount points for the same filesystem
  • Network filesystems (NFS, SMB) may report differently
  • Virtual filesystems (proc, sysfs) have special characteristics

For scripts processing many files:

  • Cache filesystem information when possible
  • Avoid repeated calls to external commands
  • Consider using /proc/mounts on Linux for faster access