Very new to Raspberry Pi and bash, but working on a headless server that will run a streaming app from USB audio card.
The plan is to take a USB card with settings file, and when inserted, the usb will automount, check for settings file, load the streamer using config file and wait for the audio input stream to start
All I have to date is generic udev rules and mount/unmount scripts ready to add code to see if the config file exists and start processing. I heavily borrowed ideas, code and udev manual SuperUser Answer for udev as well as the Mount Manager example
Many examples used serial numbers and volume labels - I do NOT want anything hardcoded. The goal was to be able to mount any loaded USB drive on to a script defined /media/ and use same script to unmount it if it was removed.
This has only been tested on Raspberry Pi 3 running Raspbian Jessie Lite. The only prep is to create the log and script folders defined by the config parameters at the top of the init script (and chmod 0755 scripts(
Barebones comments so far, but building documentation as I go along.
Any feedback, warnings and suggestions are much appreciated. I am very new at this and have been relying on others' examples and many man pages
/etc/udev/rules.d/85-usb-loader.rules
# /etc/udev/rules.d/85-usb-loader.rules
# ADD rule:
# if USB inserted,
# and flash drive loaded as sd#
# pass on dev id and device formatting type
# run short script to fork another processing script
# run script to initiate another script (first script must finish quickly)
# to mkdir and mount, process file
#
# REMOVE rule:
# if USB removed,
# unmount devices loaded by ADD rule
# remove mount folder created by ADD rule
#
# ** NOTE ** only add initial action parameter to ADD rule
#
# reload rules on PI by:
# > sudo udevadm control -R
#
ACTION=="add", KERNEL=="sd*[0-9]", SUBSYSTEMS=="usb", RUN+="/home/pi/scripts/usb-initloader.sh ADD %k $env{ID_FS_TYPE}"
ACTION=="remove", KERNEL=="sd*[0-9]", SUBSYSTEMS=="usb", RUN+="/home/pi/scripts/usb-initloader.sh %k"
/home/pi/scripts/usb-initloader.sh
#!/bin/bash
# /home/pi/scripts/usb-initloader.sh
#
# make sure to chmod 0755 on these scripts
#
# script that runs when usb device is inserted
# checks to see if file is on USB drive and copies it over
# eventually run a python script that loads the config file
#
# ** DEVICE ADDED **
# should be called from a udev rule like:
# passes kernel device and filesystem type
# ACTION=="add", KERNEL=="sd*[0-9]", SUBSYSTEMS=="usb", RUN+="/home/pi/scripts/usb-initloader.sh ADD %k %E{key}"
# Mounts usb device on /media/<dev>
# Logs changes to /var/log/syslog
# use tail /var/log/syslog to look at latest events in log
#
# ** DEVICE REMOVED **
# or remove - where we only need the kernel device
# should be called from a udev rule like:
# ACTION=="remove", KERNEL=="sd*[0-9]", SUBSYSTEMS=="usb", RUN+="/home/pi/scripts/usb-initloader.sh %k"
#
#
# CONFIGURATION
#
LOG_DIR=/home/pi/logs
LOG_FILE="${LOG_DIR}/usb-automount.log"
MOUNT_DIR=/media
# Call new script and leave this one (with trailing "&")
if [ "$1" == "ADD" ]; then
DEVICE="$2" # USB device name (formed with kernel passed from rule)
DEVTYPE="$3" # USB device formatting type
/home/pi/scripts/usb-automount.sh "$LOG_FILE" "$MOUNT_DIR" "$DEVICE" "$DEVTYPE" &
else
DEVICE="$1" # USB device name (formed with kernel passed from rule)
/home/pi/scripts/usb-unloader.sh "$LOG_FILE" "$MOUNT_DIR" "$DEVICE" &
fi
/home/pi/scripts/usb-unloader.sh
#!/bin/bash
# /home/pi/scripts/usb-unloader.sh
# Called from /home/pi/scripts/usb-initloader.sh
# make sure to chmod 0755 on file
# UnMounts usb device on /media/<device>
# Logs changes to /var/log/syslog and local log folder
# use tail /var/log/syslog to look at latest events in log
# CONFIGURATION
LOG_FILE="$1"
MOUNT_DIR="$2"
DEVICE="$3" # USB device name (from kernel parameter passed from rule)
# check input
if [ -z "$LOG_FILE" ]; then
exit 1
fi
if [ -z "$MOUNT_DIR" ]; then
exit 1
fi
if [ -z "$DEVICE" ]; then
exit 1
fi
dt=$(date '+%d/%m/%Y %H:%M:%S')
echo "--- USB Auto UnLoader --- $dt" >> $LOG_FILE
sudo umount "/dev/$DEVICE" >> $LOG_FILE 2>&1
sudo rmdir "$MOUNT_DIR/$DEVICE" >> $LOG_FILE 2>&1
device_is_mounted=`grep ${DEVICE} /etc/mtab`
if [ "$device_is_mounted" == "" ]; then
echo "/dev/${DEVICE} successfully UnMounted" >> $LOG_FILE 2>&1
fi
/home/pi/scripts/usb-automount.sh
#!/bin/sh
#
# Script: /home/pi/scripts/usb-automount.sh
# make sure to chmod 0755 on this script
# In case process of mounting takes too long for udev
# we call this script from /home/pi/scripts/usb-initloader.sh
#
# USAGE: usb-automount.sh DEVICE FILESYSTEM
# DEVICE is the actual device node at /dev/DEVICE (returned by udev rules %k parameter)
# FILESYSTEM is the FileSystem type returned by rules (returned by udev rules %E{ID_FS_TYPE} or $env{ID_FS_TYPE}
#
# This script takes a device name, file system type, creates /media/DEVICE and mounts the partition.
#
# Adapted for Raspberry Pi - Raspbian O/S
# from previous code found at:
# https://superuser.com/questions/53978/automatically-mount-external-drives-to-media-label-on-boot-without-a-user-logge
# and mount manager example at
# http://solvedforhome.com/?p=2806&v=3a52f3c22ed6
LOG_FILE="$1"
MOUNT_DIR="$2"
DEVICE="$3" # USB device name (from kernel parameter passed from rule)
FILESYSTEM="$4"
# check input
if [ -z "$LOG_FILE" ]; then
exit 1
fi
if [ -z "$MOUNT_DIR" ]; then
exit 1
fi
if [ -z "$DEVICE" ]; then
exit 1
fi
if [ -z "$FILESYSTEM" ]; then
exit 1
fi
# Allow time for device to be added
sleep 1
dt=$(date '+%d/%m/%Y %H:%M:%S')
echo "--- USB AutoLoader --- $dt" >> $LOG_FILE
# test that this device isn't already mounted
device_is_mounted=`grep ${DEVICE} /etc/mtab`
if [ -n "$device_is_mounted" ]; then
echo "Error: seems /dev/${DEVICE} is already mounted" >> $LOG_FILE 2>&1
exit 1
fi
# test mountpoint - it shouldn't exist
if [ ! -e "$MOUNT_DIR/${DEVICE}" ]; then
# make the mountpoint
sudo mkdir "$MOUNT_DIR/${DEVICE}" >> $LOG_FILE 2>&1
# make sure the Pi user owns this folder
sudo chown -R pi:pi "$MOUNT_DIR/${DEVICE}" >> $LOG_FILE 2>&1
# mount the device base on USB file system
case "$FILESYSTEM" in
vfat) sudo mount -t vfat -o utf8,uid=pi,gid=pi "/dev/${DEVICE}" "$MOUNT_DIR/${DEVICE}" >> $LOG_FILE 2>&1
;;
# use locale setting for ntfs
ntfs) sudo mount -t auto -o uid=pi,gid=pi,locale=en_US.UTF-8 "/dev/${DEVICE}" "$MOUNT_DIR/${DEVICE}" >> $LOG_FILE 2>&1
;;
# ext2/3/4 do not like uid option
ext*) sudo mount -t auto -o sync,noatime "/dev/${DEVICE}" "$MOUNT_DIR/${DEVICE}" >> $LOG_FILE 2>&1
;;
esac
# Allow time for device to be mounted
sleep 2
device_is_mounted=`grep ${DEVICE} /etc/mtab`
if [ -n "$device_is_mounted" ]; then
echo "/dev/${DEVICE} successfully mounted" >> $LOG_FILE 2>&1
fi
# all done here, return successful
exit 0
fi
exit 1