4

For the project SamplerBox, up to now I was using /dev/sda1 /media auto nofail 0 0 to have USB flash drives automatically mounted when inserted on the headless computer, see also Auto-mount and auto-remount with /etc/fstab. But this seems not very reliable, for example, when an USB flash drive is removed, and then re-inserted.

What lightweight and easy-to-configure solution is available in Debian to automatically mount every /dev/sd* device to /media/?

  • If a second flash drive is plugged, ignore or mount to another folder /media2/

  • If a drive is removed (even without a proper umount), and then re-inserted a few minutes later it should be mounted again

The use case is a headless device on which the end user can plug USB flash drives, and it should be always recognized (no matter if they removed the previous USB flash drive without asking permission in the software).

2
  • 4
    Have you considered udev + systemd yet? A guide
    – FelixJN
    Commented Dec 14, 2021 at 10:52
  • 3
    Excellent solution @FelixJN, thanks a lot! I adapted this code to my needs (essentially step #1 below), and I posted an answer (citing you and the original author of course). Thanks again!
    – Basj
    Commented Dec 14, 2021 at 12:16

1 Answer 1

7

Based on @FelixJN's comment, I slightly modified this excellent guide by Andrea Fortuna according to my needs and here is the solution:

  1. Create a file /root/usb-mount.sh containing this (and add +x permission):

    #!/bin/bash
    ACTION=$1
    DEVBASE=$2
    DEVICE="/dev/${DEVBASE}"
    MOUNT_POINT=$(/bin/mount | /bin/grep ${DEVICE} | /usr/bin/awk '{ print $3 }')  # See if this drive is already mounted
    case "${ACTION}" in
        add)
            if [[ -n ${MOUNT_POINT} ]]; then exit 1; fi          # Already mounted, exit
            eval $(/sbin/blkid -o udev ${DEVICE})                # Get info for this drive: $ID_FS_LABEL, $ID_FS_UUID, and $ID_FS_TYPE
            OPTS="rw,relatime"                                   # Global mount options
            if [[ ${ID_FS_TYPE} == "vfat" ]]; then OPTS+=",users,gid=100,umask=000,shortname=mixed,utf8=1,flush"; fi     # File system type specific mount options
            if ! /bin/mount -o ${OPTS} ${DEVICE} /media/; then exit 1; fi          # Error during mount process: cleanup mountpoint
            ;;
        remove)
            if [[ -n ${MOUNT_POINT} ]]; then /bin/umount -l ${DEVICE}; fi
            ;;
    esac
    
  2. Create a file /etc/systemd/system/[email protected] containing:

    [Unit]
    Description=Mount USB Drive on %i
    
    [Service]
    Type=oneshot
    RemainAfterExit=true
    ExecStart=/root/usb-mount.sh add %i
    ExecStop=/root/usb-mount.sh remove %i
    
  3. Create a file /etc/udev/rules.d/99-local.rules containing:

    KERNEL=="sd[a-z][0-9]", SUBSYSTEMS=="usb", ACTION=="add", RUN+="/bin/systemctl start usb-mount@%k.service"
    KERNEL=="sd[a-z][0-9]", SUBSYSTEMS=="usb", ACTION=="remove", RUN+="/bin/systemctl stop usb-mount@%k.service"
    
  4. Restart the rules:

     udevadm control --reload-rules
     systemctl daemon-reload
    
  5. Plug a USB flash drive. It should be mounted to /media/.

1
  • Code only is not an answer. Please describe what happens here. Bash script is hard to understand. Why is there the need for a systemd-unit/service?
    – buhtz
    Commented May 19 at 8:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .