Okay, so I had a go and came up with the following solution; it's not desperately pretty, but mount and df should be available on most unix flavours, and this should return the correct device identifier by working through volumes until it can go no further. In most cases it should only require one or two iterations.
function get_device() {
fs=$(df -k "$1" | tail -1)
# Determine the device for the file-system
device=
mnt=$(echo "$fs" | awk '{ print $6 }')
if [ "$cached_mnt" != "$mnt" ]
then
cached_mnt="$mnt"
mnts=$(mount)
newmnt="$mnt"
# Try to get a root mount point (for encrypted folders etc.)
while [ -n "$newmnt" ]
do
newmnt=$(echo "$mnts" | grep " on $mnt " | awk '{ print $1 }')
[ "$newmnt" = "$mnt" ] && break
if [ -n "$newmnt" ]
then
device="$newmnt"
mnt=$(df "$newmnt" 2> /dev/null | tail -1 | awk '{print $6 }')
[ "$mnt" = "$device" -o "$mnt" = "$last" ] && break
last="$mnt"
fi
done
cached_device="$device"
else
device="$cached_device"
fi
echo "$device"
}
Forgive any typos, as it's from a larger script. It uses very simple caching in case multiple device queries are made that resolve to the same disk/partition.