scripts/testing/udevmonitord.py

95 lines
2.5 KiB
Python
Executable File

#!/usr/bin/python
"""
udevmonitord runs in the background and monitors changes in plugged devices
Examples:
# Print to console
./udevmonitord.py -s 'echo "Device $action $sys_name:$sys_number, $device_type"'
# Show notification
./udevmonitord.py -s 'notify-send "Device $action $sys_name:$sys_number, $device_type"'
# Run script
./udevmonitord.py -s /home/lanxu/Scripts/echo.sh
"""
import os
import re
import sys
import getopt
import pyudev
import subprocess
import logging
__author__ = 'lanxu <jukka.lankinen@gmail.com>'
LOGGING_FORMAT = "%(asctime)s %(levelname)s %(message)s"
def main(argv):
''' main function to parse input and setup logging'''
loglevel = logging.ERROR
log_file = __file__ + '.log'
script_file = None
try:
opts, args = getopt.getopt(argv,"hs:l:v",["scriptfile=","logfile="])
except getopt.GetoptError:
print('test.py -i <inputfile> -o <outputfile>')
sys.exit(1)
for opt, arg in opts:
if opt == '-h':
print(__file__ + ' -l logfile.log -s script.sh [-v]')
sys.exit()
elif opt in ("-v", "--verbose"):
loglevel = logging.DEBUG
elif opt in ("-l", "--logfile"):
log_file = arg
elif opt in ("-s", "--scriptfile"):
script_file = arg
logging.basicConfig(format=LOGGING_FORMAT, level=loglevel, handlers=[logging.FileHandler(log_file), logging.StreamHandler()])
monitor(script_file)
def monitor(script_file):
''' Start monitoring main loop'''
context = pyudev.Context()
monitor = pyudev.Monitor.from_netlink(context)
# Iterate over polled devices
for device in iter(monitor.poll, None):
# Filter out none types
if device.device_type is not None:
args = {
'action': device.action,
'sys_name': device.sys_name,
'sys_number': device.sys_number,
'driver': device.driver,
'device_type': device.device_type
}
logging.debug(args)
# Run script if it is defined
if script_file:
script_env = os.environ.copy()
for key, value in args.items():
if value is not None:
script_env[key] = value
try:
subprocess.run([script_file], shell=True, check=True, env=script_env)
except:
logging.error('Something went wrong!')
if __name__ == "__main__":
main(sys.argv[1:])