Skip to content

Instantly share code, notes, and snippets.

@shouya
Last active August 29, 2015 14:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shouya/a9ca5e2a528cc1103272 to your computer and use it in GitHub Desktop.
Save shouya/a9ca5e2a528cc1103272 to your computer and use it in GitHub Desktop.
monitor on file creation and run corresponding scripts (based on inotify)

Edit the script source code

There is a baseDir variable for which you can designate the directory you want to monitor.

The variable monitors can be edited according to the lock files to be monitored and the corresponding script files to be executed when the lock files were created.

Setup udev rules

# /etc/udev/rules.d/80-filco-keyboard.rules     
ACTION=="add",DRIVER=="usb",ATTRS{product}=="USB Keyboard",RUN+="touch /tmp/keyboard.lock && rm /tmp/keyboard.lock"

# /etc/udev/rules.d/81-wacom.rules
ACTION=="add",DRIVER=="wacom",RUN+="touch /tmp/wacom.lock && rm /tmp/wacom.lock"

Test to ensure the file /tmp/<device>.lock was created as attached the device. (inotifywait -m -e CREATE /tmp)

Get haskell ready

For gentoo:

# emerge -av ghc cabal cabal-install
#/$ cabal install hinotify

(Optional) Compile the script

ghc -O2 -o watchtight.hexe watchtight.hs

Run on startup

Add the following line to where you want the monitor to be established, such as ~/.xinitrc and ~/.xprofile.

nohup /path/to/watchtight.hexe &

If you didn't compile the script, use the following line instead:

nohup runghc /path/to/watchtight.hs &
#!/usr/bin/env runghc
{-# LANGUAGE RecordWildCards #-}
{- Dependencies
* cabal install hinotify
-}
import System.INotify
import System.Process
import System.Exit
import System.IO
import System.FilePath.Posix
import System.Posix.Signals
import Control.Monad
import Data.Map (Map)
import qualified Data.Map as M
import Control.Concurrent
baseDir :: String
baseDir = "/tmp"
monitors :: [(FilePath, FilePath)]
monitors = [
("keyboard.lock", "/home/shou/script/new_keyboard_connected.sh"),
("wacom.lock", "/home/shou/script/setup_wacom.sh")
]
handle :: Event -> IO ()
handle Created {..} = mapM_ (uncurry $ checkAndRunScript filePath) monitors
handle _ = return ()
checkAndRunScript :: FilePath -> FilePath -> FilePath -> IO ()
checkAndRunScript newfile lockfile scriptfile
| newfile `equalFilePath` lockfile = do
hPutStrLn stderr (lockfile ++ " created, executing " ++ scriptfile)
callProcess "bash" [scriptfile]
| otherwise = return ()
makeSignalSet :: [Signal] -> SignalSet
makeSignalSet [] = emptySignalSet
makeSignalSet (x:xs) = addSignal x $ makeSignalSet xs
main :: IO ()
main = do
tid <- myThreadId
inotify <- initINotify
wd <- addWatch inotify [Create] baseDir handle
let closeAndExit = Catch $ do
removeWatch wd
killThread tid
installHandler sigINT closeAndExit Nothing
installHandler sigTERM closeAndExit Nothing
forever $ threadDelay 10000000
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment