Reporting new USB storage devices on Linux and macOS with Python
This script might get the job done, but it is a rather crude and inefficient hack.  Ideally, you should avoid polling every quarter second (or polling at all).  Also, I see no reason to write any files to /tmp.



The ideal way to do it in Linux is to use udev.  If you don't want to write a persistent udev rule, or you don't have root access, you can run /sbin/udevadm monitor --udev --property as a child process, and trigger your test whenever udevadm offers output.  For a smarter script, you can can look for the ACTION=add line and take advantage of the information in the SUBSYSTEM=… and DEVPATH=… lines.  DEVPATH tells you path to the device within /sys.  But, even if you simply trigger your script only when any output appears, that would be a huge improvement over polling four times a second.

import itertools
from subprocess import Popen, PIPE
import re
import sys

KEYVALUE_RE = re.compile(r'([^=]+)=(.*)')

def events(stream):
    """
    Read udev events from the stream, yielding them as dictionaries.
    """
    while True:
        event = dict(
            KEYVALUE_RE.match(line).groups()
            for line in itertools.takewhile(KEYVALUE_RE.match, stream)
        )
        if event:
            yield event

try:
    UDEVADM = ['/sbin/udevadm', 'monitor', '--udev', '--property']
    with Popen(UDEVADM, stdout=PIPE, encoding='UTF-8') as udevadm:
        for event in events(udevadm.stdout):
            if event['ACTION'] == 'add' and event.get('DRIVER') == 'usb-storage':
                print(event)
                break
except KeyboardInterrupt:
    sys.exit(1)




On macOS, you can get similar information by running and monitoring the output of /usr/sbin/diskutil activity, if you are interested in storage devices.  Look for lines starting with ***DiskAppeared.

from subprocess import Popen, PIPE
import sys

try:
    DISKUTIL = ['/usr/sbin/diskutil', 'activity']
    with Popen(DISKUTIL, stdout=PIPE, encoding='UTF-8') as diskutil:
        # Ignore events that describe the present state
        for line in diskutil.stdout:            
            if line.startswith('***DAIdle'):    
                break
        # Detect the first subsequent "Disk Appeared" event 
        for line in diskutil.stdout:
            if line.startswith('***DiskAppeared'):
                print(line)
                break
except KeyboardInterrupt:
    sys.exit(1)


If you are interested in non-storage devices as well, then you could take advantage of the File System Events API, possibly through the MacFSEvents Python package or the cross-platform fswatch program.