Setup is simple. I have a rack-mounted server with 24 5" drive bays in the front. The server runs PLEX. Each HDD is NTFS partitioned and contain optional folders in root. Server is running Debian8 (3.16.51-3)

Requirements: I need to be able to plug-and-play HDDs, auto-mount NTFS partitions, scan for the existence of pre-defined folders, and symlink to a PLEX oriented directory. Mounts and Symlinks should default to using the UUID

Optional Folders / Plex Directory:


UDEV Hook: /etc/udev/rules.d/sata-rackmount.rules

ACTION=="add", KERNEL=="sd?", RUN+="/plex/new_drive.sh"

*Note: udevadm control --reload-rules to reload after making changes *Note: udevadm monitor --udev can be used to see mounting changes

BASH: /plex/new_drive.sh


echo "New Drive Detected" >> /plex/log.txt
echo "\tLABEL: ${ID_SERIAL_SHORT}" >> /plex/log.txt
echo "\tNAME: ${DEVNAME}" >> /plex/log.txt

echo "\tMOUNT required" >> /plex/log.txt
for block in $( blkid -t TYPE=ntfs | grep "${DEVNAME}" )
    echo "\t > Block Found"
    BLK=$(echo '$block' | sed -rn 's/^(\/dev\/sd[a-z][0-9]):.*\bUUID\b[=]["]([^"]*)["].*$/\1/p')
    UUID=$(echo '$block' | sed -rn 's/^(\/dev\/sd[a-z][0-9]):.*\bUUID\b[=]["]([^"]*)["].*$/\2/p')
    echo "\tMounting Point: $BLK > $UUID" >> /plex/log.txt

*Note: This script needs to be CHOWN root:root new_drive.sh and CHMOD +x new_drive.sh for UDEV to have access

Current log.txt:

New Drive Detected
    LABEL: WD-WCANKC405910
    NAME: /dev/sdf
    MOUNT required

Output of blkid | grep (foreach)

/dev/sdf1: UUID="A2F66547F6651CB3" TYPE="ntfs" PARTUUID="1549f232-01"

Output of sed (on above output)

\1 = /dev/sdf1
\2 = A2F66547F6651CB3

The current problem appears to be with my for-in loop, which the code is skipping right over. All of my research suggests that should work, not sure why it isn't.

For testing purposes, the UDEV hook will have to be modified for your own systems in case you decide to use alternative media sources, as 'sd?' will only match SATA based drives, only on the root drive (IE not /dev/sdf1), and assumes nothing else is known about the drive before the script runs.


There were a few problems I had to fix. Firstly, for block in $(...) resulted in 4 rows of data, not the single. The line was also extremely stingy about how I added the variable, and would skip if it wasn't perfect. When obtaining BLK and UUID, it's important to note that apostrophe's ' don't read variables.

echo "New Drive Detected" >> /plex/log.txt
echo "\tLABEL: ${ID_SERIAL_SHORT}" >> /plex/log.txt
echo "\tNAME: ${DEVNAME}" >> /plex/log.txt

#fixed to collect output line, instead of arguments
for block in "$( blkid -t TYPE=ntfs | grep ${DEVNAME} )";
    echo "\tPartition Found: $block" >> /plex/log.txt
    BLK=$(echo "$block" | sed -rn 's/^(\/dev\/sd[a-z][0-9]):.*\bUUID\b[=]["]([^"]*)["].*$/\1/p')
    UUID=$(echo "$block" | sed -rn 's/^(\/dev\/sd[a-z][0-9]):.*\bUUID\b[=]["]([^"]*)["].*$/\2/p')
    echo "\tMounting Point: $BLK > /media/$UUID" >> /plex/log.txt
    mkdir -p "/media/$UUID"
    #repair in case of exclusivity
    #ntfsfix "$BLK"
    mount -t ntfs-3g -U "$UUID" "/media/$UUID"
    if [ -d "/media/$UUID/movies" ]; then
        echo "\tMovie Directory Found" >> /plex/log.txt
        mkdir -p "/plex/movies"
        ln -s "/media/$UUID/movies" "/plex/movies/$UUID"
    if [ -d "/media/$UUID/tvseries" ]; then
        echo "\tTV Directory Found" >> /plex/log.txt
        mkdir -p "/plex/tvseries"
        ln -s "/media/$UUID/tvseries" "/plex/tvseries/$UUID"
    if [ -d "/media/$UUID/anime" ]; then
        echo "\tAnime Directory Found" >> /plex/log.txt
        mkdir -p "/plex/anime"
        ln -s "/media/$UUID/anime" "/plex/anime/$UUID"
    if [ -d "/media/$UUID/music" ]; then
        echo "\tMusic Directory Found" >> /plex/log.txt
                mkdir -p "/plex/music"
                ln -s "/media/$UUID/music" "/plex/music/$UUID"
    if [ -d "/media/$UUID/audiobooks" ]; then
        echo "\tAudio Book Directory Found" >> /plex/log.txt
        mkdir -p "/plex/audiobooks"
        ln -s "/media/$UUID/audiobooks" "/plex/audiobooks/$UUID"

This script works so long as the drive doesn't have the "windows protected" flag, fixed by NTFSFIX "$BLK", but no matter how hard I try, I can't get it to fix synchronously with the script activity (new problem I'll have to research). I've confirmed it DOES execute, but the subsequent mount seems to execute before it's finished. I assume this because I have to first unmount the drive, then run NTFSFIX, then mount the drive again. I also found a minor issue with the drive not unmounting automatically, and would remount with a new drive letter each subsequent time. That was solved by another script with another UDEV argument:

UDEV: /etc/udev/rules.d/sata-rackmount.rules

ACTION=="add", KERNEL=="sd?", RUN+="/plex/new_drive.sh"
ACTION=="remove", KERNEL=="sd??", RUN+="/plex/rem_drive.sh"



echo "Drive Lost" >> /plex/log.txt
echo "\tLABEL: ${ID_SERIAL_SHORT}" >> /plex/log.txt
echo "\tNAME: ${DEVNAME}" >> /plex/log.txt

echo "\tDismounting..." >> /plex/log.txt
umount "${DEVNAME}"
echo "\tDone!" >> /plex/log.txt

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.