1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 '''
23 inotifyx is a simple Python binding to the Linux inotify file system event
24 monitoring API.
25
26 Generally, usage is as follows:
27
28 >>> fd = init()
29 >>> try:
30 ... wd = add_watch(fd, '/path', IN_ALL_EVENTS)
31 ... events = get_events(fd)
32 ... rm_watch(fd, wd)
33 ... finally:
34 ... os.close(fd)
35 '''
36
37 import os, select
38
39 import _inotifyx
40
41
42 constants = {}
43
44 for name in dir(_inotifyx):
45 if name.startswith('IN_'):
46 globals()[name] = constants[name] = getattr(_inotifyx, name)
47
48
49 init = _inotifyx.init
50 rm_watch = _inotifyx.rm_watch
51 add_watch = _inotifyx.add_watch
52
53
55 '''
56 InotifyEvent(wd, mask, cookie, name)
57
58 A representation of the inotify_event structure. See the inotify
59 documentation for a description of these fields.
60 '''
61
62 wd = None
63 mask = None
64 cookie = None
65 name = None
66
67 - def __init__(self, wd, mask, cookie, name):
72
75
77 return '%s(%s, %s, %s, %s)' % (
78 self.__class__.__name__,
79 repr(self.wd),
80 repr(self.mask),
81 repr(self.cookie),
82 repr(self.name),
83 )
84
86 '''
87 Return an ASCII string describing the mask field in terms of
88 bitwise-or'd IN_* constants, or 0. The result is valid Python code
89 that could be eval'd to get the value of the mask field. In other
90 words, for a given event:
91
92 >>> from inotifyx import *
93 >>> assert (event.mask == eval(event.get_mask_description()))
94 '''
95
96 parts = []
97 for name, value in constants.items():
98 if self.mask & value:
99 parts.append(name)
100 if parts:
101 return '|'.join(parts)
102 return '0'
103
104
106 '''
107 get_events(fd[, timeout])
108
109 Return a list of InotifyEvent instances representing events read from
110 inotify. If timeout is None, this will block forever until at least one
111 event can be read. Otherwise, timeout should be an integer or float
112 specifying a timeout in seconds. If get_events times out waiting for
113 events, an empty list will be returned. If timeout is zero, get_events
114 will not block.
115 '''
116 return [
117 InotifyEvent(wd, mask, cookie, name)
118 for wd, mask, cookie, name in _inotifyx.get_events(fd, *args)
119 ]
120
121
122 if __name__ == '__main__':
123 import sys
124
125 if len(sys.argv) == 1:
126 print >>sys.stderr, 'usage: inotify path [path ...]'
127 sys.exit(1)
128
129 paths = sys.argv[1:]
130
131 fd = init()
132
133 wd_to_path = {}
134
135 try:
136 for path in paths:
137 wd = add_watch(fd, path)
138 wd_to_path[wd] = path
139
140 try:
141 while True:
142 events = get_events(fd)
143 for event in events:
144 path = wd_to_path[event.wd]
145 parts = [event.get_mask_description()]
146 if event.name:
147 parts.append(event.name)
148 print '%s: %s' % (path, ' '.join(parts))
149 except KeyboardInterrupt:
150 pass
151
152 finally:
153 os.close(fd)
154