How to detect if a filesystem supports permissions?

205 Views Asked by At

Recently I ran into an issue when my script extracts temporary files via tar to a folder choosen by the user.

The problem was that if that folder was on a USB stick with exfat filesystem, the extracted files loose the permission information that ext4 and btrfs filesystems store with each file.

To solve this I created the following fix:

#!/usr/bin/env bash

FOLDER="/example"
FS=$(stat -f -c %T "$FOLDER")

if [[ "$FS" == "fat"* || "$FS" == "vfat"* || "$FS" == "exfat"* || "$FS" == "ntfs"* || "$FS" == "fuse"* || "$FS" == "msdos"* ]]; then
  echo "Unsupported filesystem!"
  exit
fi

While this works, it requires me to keep a list of which filesystems are incompatible with ext4 permissions, and I'm sure my list is far from complete. Because there exist dozens of exotic filesystems that may have the same issue.

So is there a better way to test if a folder supports permissions without actually having to write a file first? And if not, what filesystems should I add to this list to make it more complete?

2

There are 2 best solutions below

2
On BEST ANSWER

Might be ok to check if one can change write permission and make it a function:

#!/usr/bin/env sh

# Checks path support changing write permissions
# @args
#     $1: The path to check (mandatory)
# @return
#     0: Allow changing write permission
#     1: Does not allow changing write permission
#     2: Cannot perform the check
canChangeWritePermission() {
    [ -d "${1:?}" ] || return 2
    __cCWP_tmpFile=$(TMPDIR=$1 mktemp) || return 2

    if
        chmod -w "$__cCWP_tmpFile" && ! [ -w "$__cCWP_tmpFile" ] &&
        chmod +w "$__cCWP_tmpFile" && [ -w "$__cCWP_tmpFile" ]
        then rc=0
        else rc=1
    fi
    rm -f -- "$__cCWP_tmpFile"
    return $rc
}

if canChangeWritePermission "${1:?}" 2>/dev/null
then printf '%s has support for changing write permission.\n' "$1"
elif [ $? -eq 1 ]
    then printf '%s does not allow changing write permission.\n' "$1"
    else printf 'Cannot check %s\n' "$1" >&2
fi
1
On
tempfile=$(mktemp)
chmod 600 "$tempfile" 2>/dev/null
if [ $? -eq 0 ]; then
    echo "Filesystem supports permissions"
else
    echo "Filesystem does not support permissions"
fi
rm "$tempfile"