Скрыть 
Цель:  при вставке устройства хранения данных вызывать цепочку баш скриптов, делающее с вставленным и отмонтированным носителем разные непотребства.
Реализация:  Раньше для этого я использовал ivman, но чего-то он слишком громоздкий был. За основу взят комментер событий на питоне от radiofun, из которого вырезана часть составляющая комментарии (теперь комментируем события из баш скриптов, по мере надобности. На моей станции комментирует самописная прога на сях lsay ( проприетарный цепстраловский синтез + зажигание светодиодов в lpt в зависимости от амплитуды речи ))
Собственно сырец маунт манагера и комменты к нему ниже
python #!/usr/bin/python # -*- coding: utf-8 -*- ########################################################################### #  Event Commenter + automount via hal  + bash handlers                   #  # ------------------------------                                          # # copyright : © 2008 radiofun; © 2009 Necromant                           # # jabber    : [email protected]                                           # # jabber    : [email protected]                                        # #                                                                         # ########################################################################### #                                                                         # #   This program is free software; you can redistribute it and/or modify  # #   it under the terms of the GNU General Public License as published by  # #   the Free Software Foundation; either version 2 of the License, or     # #   (at your option) any later version.                                   # #                                                                         # ########################################################################### import  gobjectimport  threading import  math import  dbusimport  dbus.mainloop .glib import  os "/home/aifiltr0/.config/NMountManager/storage_handler.sh" class  NMountMgr( ) :#threading.Thread): def  __init__ ( self ) :#threading.Thread.__init__(self) self .__bus = dbus.SystemBus ( ) self .__hm = self .__bus.get_object ( 'org.freedesktop.Hal' ,'/org/freedesktop/Hal/Manager' ) self .__hm.connect_to_signal ( 'DeviceAdded' , self .deviceAdded ) self .__hm.connect_to_signal ( 'DeviceRemoved' , self .deviceRemoved ) self .handler_script  = handler_scriptself .__connectedDevices = dict ( ) ; def  deviceAdded( self , devID) :Interface ( self .__bus.get_object ( "org.freedesktop.Hal" , devID) ,"org.freedesktop.Hal.Device" ) self .__prepareAction( device) if  len ( exec_line)  >  0:self .__connectedDevices[ devID] =exec_lineos .system ( self .handler_script  + " connect "  + exec_line) ; def  deviceRemoved( self , devID) :if  devID in  self .__connectedDevices:self .__connectedDevices.pop ( devID) os .system ( self .handler_script  + " disconnect "  + exec_line) ; #self.__say(message); #prepare device comment! def  __prepareAction( self , device) :"" if  device.PropertyExists ( 'info.capabilities' ) :QueryCapability ( 'volume.disc' ) #if "volume" if  device.QueryCapability ( 'volume' )  and  not  isCD:self .__getHumanReadableSize( device.GetProperty ( 'volume.size' ) ) GetProperty ( 'volume.label' ) if  len ( label)  <  1 :GetProperty ( 'volume.fsversion' ) #message += "Volume connected: label is " + label + ", Total size "+ size #device.Mount(label,"rw"); GetProperty ( 'volume.uuid' ) replace ( "-" ,"_" ) self .__bus.get_object ( 'org.freedesktop.Hal' , '/org/freedesktop/Hal/devices/volume_uuid_'  + uuid) #Dirty hack for vfat unicode mount # if  ( device.GetProperty ( 'volume.fstype' ) =='vfat' ) :( "utf8" ,"uid=1000" ,"shortname=mixed" ) ; else :( "uid=1000" ) ; Mount ( '' , device.GetProperty ( 'volume.fstype' ) , mopts , dbus_interface="org.freedesktop.Hal.Device.Volume" ) GetProperty ( 'volume.mount_point' ) " volume \" "  + mpoint + "\"  \" "  + label + "\"  "  + uuid# if CD or dvd # I have no cd/dvd on my netbook, so the following is not well tested if  isCD:"" if  device.GetProperty ( 'volume.disc.has_audio' ) :" audio " if  device.GetProperty ( 'volume.disc.is_blank' ) :" empty " GetProperty ( 'volume.disc.type' )  + " " GetProperty ( 'volume.label' ) GetProperty ( 'volume.uuid' ) replace ( "-" ,"_" ) self .__bus.get_object ( 'org.freedesktop.Hal' , '/org/freedesktop/Hal/devices/volume_uuid_'  + uuid) Mount ( '' , device.GetProperty ( 'volume.fstype' ) , "" , dbus_interface="org.freedesktop.Hal.Device.Volume" ) GetProperty ( 'volume.mount_point' ) " cd \" "  + mpoint + "\"  \" "  + label + "\"  "  + uuid#if storage elif  device.QueryCapability ( 'storage' ) :#message += 'Device connection detected: ' #message += self.__getDeviceName(device) + " storage" "stgdev \" "  + self .__getDeviceName( device)  + "\" " #это должно быть саммы последним!             elif  ( device.PropertyExists ( 'linux.subsystem' ) and  ( device.GetProperty ( 'linux.subsystem' )  == 'usb' ) )  :GetProperty ( 'info.category' ) self .__getDeviceName( device) #message += devName + " " + category "usbdev \" "  + self .__getDeviceName( device)  + "\" " return  exec_line# in uint64! def  __getHumanReadableSize( self , size) :int ( math .log ( size, 1024) ) { lambda  x: str ( x)  + ' bytes' ,lambda  x: str ( int ( x/1024 +0.5 ) )  + ' kilobytes' ,lambda  x: str ( int ( x/1.048576e6+0.5 ) )  + ' megabytes' ,lambda  x: str ( int ( x/1.073741824e9+0.5 ) )  + ' gigabytes' } [ dim] ( size) return  resultdef  __getDeviceName( self , device) :"" if  device.PropertyExists ( 'info.vendor' ) :GetProperty ( 'info.vendor' )  + " " if  device.PropertyExists ( 'info.product' ) :GetProperty ( 'info.product' ) else :"unknown" return  resultdef  __say( self , text) :#pipe = os.popen('espeak -vmb/mb-fr4-en -s 150 -a 100','w') os .popen ( 'lsay \' '  + text+ '\' ' ,'w' ) print  text#pipe.write(text) close ( ) def  __del__  ( self ) :self .__bus.close ( ) mainloop .glib .DBusGMainLoop ( set_as_default=True ) ( ) MainLoop ( ) run ( ) В самом начале поправьте урл скрипта-хэндлера. у меня он на баше, но Вы можете его на чем угодно делать. Его задача минимальна, исходник привожу ниже. из папки handler_dir (не забудьте выставить свою!) Вызывает все скрипты предварительно установив полученные аргументы в переменные к которым легко обращаться и export’нув их.
bash #!/bin/bash handler_dir ="/home/aifiltr0/.config/NMountManager/stg_handlers.d/" ( ) { kdialog  --passivepopup  "$1"  --title  "NMountManager" & "$1" } #Comment this if you do not want reports about what is connected ( ) { } export  reportecho  $1 $2 $3 $4 $5ACTION =$1export  ACTIONTYPE =$2export  TYPEcase  "$TYPE "  in ) MPOINT =$3LABEL =$4UUID =$5export  MPOINTexport  LABELexport  UUIDif  [  $ACTION  == "connect"  ] ; then "A new storage volume has been connected. Label is $LABEL . I have attached it to $MPOINT " else "Storage volume $LABEL  removed" fi ;; cd ) MPOINT =$3LABEL =$4UUID =$5export  MPOINTexport  LABELexport  UUIDif  [  $ACTION  == "connect"  ] ; then "A compact disk has been inserted. Label is $LABEL . I have attached it to $MPOINT " else "Compact disk ejected." fi ;; ) DEVICENAME =$3export  DEVICENAMEif  [  $ACTION  == "connect"  ] ; then "A storage device called $DEVICENAME  has been connected. " fi ;; ) DEVICENAME =$3export  DEVICENAMEif  [  $ACTION  == "connect"  ] ; then "A USB device called $DEVICENAME  has been connected. " else "A USB device called $DEVICENAME  has been disconnected. " fi ;; esac BROWSEABLE =0if  [  $ACTION  == "connect"  ] ; then if  [  $TYPE  == "cd"  ] ; then echo  "cd" BROWSEABLE =1fi if  [  $TYPE  == "volume"  ] ; then echo  "vol" BROWSEABLE =1fi fi export  BROWSEABLEecho  "$ACTION  TYPE: $TYPE  MPOINT=$MPOINT  LABEL=$LABEL  UUID=$UUID  BROWSEABLE=$BROWSEABLE " cd  $handler_dir rm  * ~for  file  in  ` ls ` ; do $file done ;В папке с хэндлерами мы можем складывать свои баш скрипты на все случае жизни. Из каждого скрипта нам доступно: $ACTION – connect или disconnect $TYPE – тип устройства: usbdev, stgdev, cd, volume. Последние два монтируются автоматом, а куда именно – узнать можем через $MPOINT. Там путь к точке монтирования. $BROWSEABLE – это для ленивых, чтобы не проверять несколько разом и сэкономить на ифе: Если 1 – значит нечто отмонтировано и в $MPOINT можно минимум почитать данные. usbdev и stgdev выставляют $DEVICENAME, для cd и volume есть еще $LABEL и $UUID, так что свои флешки распознатиь легко.
Вот примеры простых скриптов-хэндлеров: Этот проверяет по ууиду (ам) моя ли эта флешка и экспортирует переменную STG_OWNER.
bash #!/bin/bash # This script checks who does this storage belong to.  # And exports a variable # This can be: 0 - ours 1 - foreign, quite simple, but nevertheless stg_pdacard =B4DC_999E( ) { for  dev in  $@ ; do if  [  "$dev "  == "$UUID "  ] ; then echo  "$dev  matched owner list!" return  0 ;fi done ;return  1}  if  [   $BROWSEABLE  -eq  "1"  ] ; then $stg_pdacard STG_OWNER =$? echo  "OWNER IS: $STG_OWNER " export  STG_OWNERfi Я задолбался сносить с флешки автораны с вирусней, когда попользую ее на вендовозных машинах в инсте. Надо бы написать парсер авторан.инфа чтобы еще и сообразить где лежит вирусня, но лень.
bash #!/bin/bash #ToDo: Properly parse ini file to locate the f*cking shit echo  "==> $ACTION  $TYPE " if  [  $ACTION  == "connect"  ] ; then if  [  $TYPE  == "volume"  ] ; then if  [  -e  $MPOINT / autorun.inf ] ; then "Security alert! The removable device has probably been infected and is dangerous for windows systems. Initiating disinfection sequence." rm  $MPOINT / autorun.inf"Disinfection complete" fi fi fi Коммуниздим потихоньку музочку с флешек друзей в фоновом режиме. Всю, какую находим и складываем в ~/msx4sort/UUID. Зависит от первого скрипта-хэндлера, который проверяет наша ли это флешка и если наша – то игнорирует. (свою-то музыку нафига копировать?)
bash #!/bin/bash #This script make sure you get all the mp3 from a flash drive of your friend without him/her ever noticing it #Just make sure you fill in the data required TARGET_DIR =~/ msx4sort/ ( ) { echo  "`pwd`  $1" find  . -iname  $1 | while  read  FILE; do if  [  -f  "$FILE "  ] ; then if  [  !  -f  "$TARGET_DIR $FILE "  ] ; then cp  --parents  "$FILE "  "$TARGET_DIR " echo  "==>" $FILE fi fi done } if  [  $BROWSEABLE  -eq  "1"  ] ; then if  [  $STG_OWNER  ! = "0"  ] ; then "Music leech in progress." mkdir  $TARGET_DIR $UUID TARGET_DIR =$TARGET_DIR $UUID cd  $MPOINT * mp3* ogg* avi* flvelse echo  "skipping owned devices" fi fi Ну и на последок: автоматом скопировать фотографии с карточки фотика, которую определяем по ууид.
bash #!/bin/bash target_dir ="/home/aifiltr0/Фотографии" target_vid_dir ="/home/aifiltr0/кЫно/видеозаписи/с коммуникатора" if  [  $BROWSEABLE  -eq  "1"  ] ; then if  [  $UUID  == "B4DC_999E"  ] ; then "This is your smartphone's card. Multimedia data transfer in progress." cd  "$MPOINT /My Pictures" for  file  in  ` find  . -iname  \* jpg` ; do mv  "$file "  "$target_dir /$file " done ;cd  "$MPOINT /My Videos" for  file  in  ` find  . -iname  \* 3gp` ; do mv  "$file "  "$target_vid_dir /$file " done ;"Transfer complete" fi fi Все скрипты пронумерованы, то есть в имени в лучших традиция 00, 01, 02 в самом начале. Так можно задать очередность выполнения. Все. спасибо radiofun за начальный скрипт.
З.Ы. Там в самом первом баш скрипте определен report() так как я кдешник, вывожу сообщения через kdialog и на синтез речи. гномерам и прочим просто поправить и все будет ку. Не забудьте на всех скриптах сделать chmod +x ну и запускать ./mount_manager.py при загрузке. Вот собственно и все, хотя по хорошему надо бы еще и код подчистить местами. 
Автор статьи AiFiLTr0 
Репост статьи с  http://invyl.ath.cx:8080/wp/?p=35