nmount (3619B)
1 #!/usr/bin/env sh 2 3 # Description: Toggle mount status of a device using pmount 4 # If the device is not mounted, it will be mounted. 5 # If the device is mounted, it will be unmounted and powered down. 6 # 7 # Dependencies: lsblk, pmount (optional), udisks2 8 # 9 # Usage: Runs `lsblk` on 'l', exits on 'Return`. 10 # 11 # Notes: 12 # - The script uses Linux-specific lsblk to list block devices. Alternatives: 13 # macOS: "diskutil list" 14 # BSD: "geom disk list" 15 # - The script uses udisksctl (from udisks2) to power down devices. This is also Linux-specific. 16 # Users on non-Linux platforms can comment it and use an alternative to power-down disks. 17 # 18 # Shell: POSIX compliant 19 # Author: Arun Prakash Jana 20 21 prompt="device name [e.g. sdXn] ('l'ist, 'q'uit): " 22 23 lsblk 24 25 printf "\nEnsure you aren't still in the mounted device.\n" 26 printf "%s" "$prompt" 27 read -r dev 28 29 while [ -n "$dev" ]; do 30 if [ "$dev" = "l" ]; then 31 lsblk 32 elif [ "$dev" = "q" ]; then 33 exit 34 else 35 # LUKS volumes mounted with udisksctl appear differently than with pmount 36 if grep -qs "$dev " /proc/mounts || [ -n "$(lsblk -n "/dev/$dev" -o MOUNTPOINT)" ]; then 37 sync "$(lsblk -n "/dev/$dev" -o MOUNTPOINT | sed "/^$/d")" 38 if type pumount >/dev/null 2>&1; then 39 pumount "/dev/$dev" 40 exit_code="$?" 41 else 42 # Unlike pmount, udisksctl does not transparently handle LUKS volumes 43 # We need to manually get the unlocked device, unmount it, and then lock the volume 44 if lsblk -n "/dev/$dev" -o FSTYPE | grep "crypto_LUKS" >/dev/null; then 45 dev_map="$(udisksctl info -b /dev/"$dev" | grep "CleartextDevice" | grep -o "dm_2d[[:digit:]]*" | sed "s/_2d/-/")" 46 udisksctl unmount -b "/dev/$dev_map" --no-user-interaction >/dev/null 47 exit_code="$?" 48 udisksctl lock -b "/dev/$dev" --no-user-interaction >/dev/null 49 else 50 udisksctl unmount -b "/dev/$dev" --no-user-interaction >/dev/null 51 exit_code="$?" 52 fi 53 fi 54 if [ $exit_code -eq 0 ]; then 55 echo "/dev/$dev unmounted." 56 if udisksctl power-off -b "/dev/$dev" --no-user-interaction; then 57 echo "/dev/$dev ejected." 58 fi 59 fi 60 elif [ -b "/dev/$dev" ]; then 61 if type pmount >/dev/null 2>&1; then 62 pmount "/dev/$dev" 63 exit_code="$?" 64 else 65 # Unlike pmount, udisksctl does not transparently handle LUKS volumes 66 # We need to manually get the unlocked device and mount that instead of the volume itself 67 if [ "$(lsblk "/dev/$dev" -n -o FSTYPE)" = "crypto_LUKS" ]; then 68 dev_map=$(udisksctl unlock -b "/dev/$dev" --no-user-interaction | grep -o "dm-[[:digit:]]*") 69 udisksctl mount -b "/dev/$dev_map" --no-user-interaction >/dev/null 70 exit_code="$?" 71 else 72 udisksctl mount -b "/dev/$dev" --no-user-interaction >/dev/null 73 exit_code="$?" 74 fi 75 fi 76 if [ $exit_code -eq 0 ]; then 77 sleep 1 78 echo "/dev/$dev mounted to $(lsblk -n "/dev/$dev" -o MOUNTPOINT | sed "/^$/d")." 79 fi 80 else 81 echo "/dev/$dev does not exist or is not a block device." 82 fi 83 fi 84 85 echo 86 printf "%s" "$prompt" 87 read -r dev 88 done