rss logo

Bash script to automated Email Notification when a USB Device is Connected

Linux terminal logo

On a Debian GNU/Linux system, I've been working on a solution to notify users by e-mail when a USB hard disk drive is connected. The aim is to inform the system administrator that the USB drive is successfully connected.

Installing and configuring msmtp

Here's an example with msmtp, which will send e-mails via the mail.std.rocks relay on SSL port 465.

  • Install msmtp:
root@host:~# apt update && apt install msmtp
  • Edit the /etc/msmtprc file:
account STD #Mail Server : host mail.std.rocks port 465 from backup@std.rocks #LOGIN / PASSWORD user backup@std.rocks password MyWeakPassword auth on tls on tls_starttls on tls_trust_file /etc/ssl/certs/ca-certificates.crt tls_certcheck off logfile /var/log/msmtp.log account default : STD

udev

udev is a device manager for GNU/Linux systems that dynamically manages devices and their corresponding device nodes in the system. It stands for "userspace device" and operates in user space rather than kernel space. It will allow us to run a script when a USB disk device is connected.

Note: let's say the disk we want to monitor is /dev/sda
  • For your information, we can display all the attributes of the /dev/sda device:
root@host:~# udevadm info --attribute-walk --path=$(udevadm info --query=path --name=/dev/sda)
  • Create a file /etc/udev/rules.d/10_usb-disk.rules:
ACTION=="add", SUBSYSTEM=="block", SUBSYSTEMS=="usb", RUN{program}+="/usr/local/sbin/mail_usb_disk.sh"
  • Reload udev rules and configuration:
root@host:~# udevadm control --reload

Bash script

  • Create the file /usr/local/sbin/mail_usb_disk.sh:
root@host:~# touch /usr/local/sbin/mail_usb_disk.sh && chmod +x /usr/local/sbin/mail_usb_disk.sh
  • Edit /usr/local/sbin/mail_usb_disk.sh:
I've noticed that the script is executed twice when a USB device is plugged in. To avoid sending two e-mails, the script creates a file /tmp/udev_time and then compares the creation time with the current time. If the time difference is greater than 10 seconds, the email will be sent.
Edit 2023/07/01: I haven't tested this, but some people say it could be solved by adding ENV{DEVTYPE}=="usb_device" to the rule. #! /bin/sh MAIL_ADDRESS="backup@std.rocks" DATE=$(/bin/date "+%Y-%m-%dT%H:%M:%S") UDEV_TIME="$(/bin/date --date="$(stat /tmp/udev_time | grep Modif | sed 's/Modif.*: //')" +%s)" #get /tmp/udev_time creation time touch /tmp/udev_time CUR_TIME="$(/bin/date +%s)" #difference between current time and /tmp/udev_time creation time TIME_DIFF=$(( (CUR_TIME - UDEV_TIME) )) #Function mailto () { LANG=C rm -f /tmp/mail_usb_disk.header echo "From: $MAIL_ADDRESS" >> /tmp/mail_usb_disk.header echo "To: $MAIL_ADDRESS" >> /tmp/mail_usb_disk.header echo "Date: "`/bin/date -R` >> /tmp/mail_usb_disk.header echo "Subject: Disk has been plugged in" >> /tmp/mail_usb_disk.header echo "Content-type: text/plain; charset=utf-8" >> /tmp/mail_usb_disk.header echo "" >> /tmp/mail_usb_disk.header echo "Disk has been plugged in" >> /tmp/mail_usb_disk.header cat /tmp/mail_usb_disk.header | /usr/bin/msmtp -f "$MAIL_ADDRESS" "$MAIL_CLIENT" rm -f /tmp/mail_usb_disk.header } #Send email if time difference is greater than 10s if [ "$TIME_DIFF" -gt 10 ]; then mailto fi
Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Contact :

contact mail address