jasonwryan.com

Miscellaneous ephemera…

Simple Unmounting

For those people that prefer to forego the full blown DE and—instead of all the “convenience” that this sort of setup offers—piece together their setup from a variety of different tools and knit it all together with some scripting, automounting external drives is, notwithstanding the inexplicable number of posts to the forums to the contrary, incredibly straightforward with udisks. My approach in this respect is to use udiskie; it is lightweight, unobtrusive, configurable and foolproof, as far as I can tell.

Where I have found a small gap, or more a minor irritation really, is with unmounting devices. udiskie-umount /media/MY_USB_DRIVE works just fine, but I often have a variety of media mounted, and not just standard USB drives. At work, for example, it is not uncommon for me to have mounted under /media any or all of the following:

  • A USB drive containing all of my music
  • An encrypted volume mounted with tcplay shared via Bittorrent Sync
  • A CIFS share
  • An NFS share or an SSHFS mount.

In a couple of these cases, I don’t want to—or can't—just umount them with udiskie; they require a different approach. To facilitate this, I have adopted a simple approach: I use a standard naming convention for all external media or their mountpoints. When I first buy a USB drive, I give it a meaningful name, beginning with an uppercase letter, as this won’t clash with any of my internal drives and it happily accommodates drives from other operating systems. So:

1
sudo dosfslabel /dev/sdc1 EightBall

sets up a new 8GB drive I found in the schwag bag at the conference I attended last week.

Now that all external media are predictably named, it is just a matter of writing a script that checks how many are mounted, presents a menu if there is more than one, and unmounts the respective device correctly:

dismount
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#!/usr/bin/env bash
# unmount USB drives

target=( $(awk '/media\/[\^A-Z]/ {print $3}' <(mount)) )
shares=(Scout Sentinel)

checkbusy() {
  grep "PID" <(lsof +d "$target" &>/dev/null)
  if [[ $? -eq 0 ]]; then
    printf "%s\n" "${target##*/} busy…"
    exit 1
  fi
}

exstatus() {
  if [[ $? -eq 0 ]]; then
    printf "%s\n" "${target##*/} unmounted…"
  else
    printf "%s\n" "Failed to unmount."
  fi
}

# check for multiple devices
if (( "${#target[@]}" > 1 )); then
  PS3="Select your device to unmount: "
  printf "%s\n" "There are ${#target[@]} devices mounted"
  select dev in "${target[@]}"; do
    target="$dev"
    break
  done
fi

# check for share
for drive in "${shares[@]}"; do
  if [[ "$drive" =~ "${target##*/}" ]]; then
    share="$drive"
  fi
done

# options per filesystem
if [[ -n "$target" ]]; then
  for drive in "${shares[@]}"; do
    if [[ "$drive" = "${target##*/}" && "${target##*/}" = Safebox ]]; then
      cmd=$(sudo safebox close)
    elif [[ "$drive" = "${target##*/}" ]]; then
      cmd=$(sudo umount "$target")
    else
      cmd=$(udiskie-umount -d "$target" &>/dev/null)
    fi
  done
# do it
checkbusy
$cmd
exstatus
else
  printf "%s\n" "No drive mounted!"
fi

# vim:set ts=2 sts=2 sw=2 et:

Now, no matter the number or type of devices I currently have mounted, I can unmount them by typing dismount and choosing the appropriate drive via the select menu. Simple, but satisfying. The script is in my bitbucket repo

Notes

Creative Commons image, Dismount, by Chris.

Comments