#!/usr/bin/python # -*- coding: iso-8859-1 -*- # # stakeout - run a command when a file in a given set changes # Copyright (C) 2004 Sami Kyöstilä # idea pillaged from: Michael McCracken # # 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. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. import sys import os from signal import signal, pause, SIGUSR1 from fcntl import fcntl, DN_MODIFY, DN_MULTISHOT, F_SETSIG, F_NOTIFY def trigger(callback, fileMap): for f, mt in fileMap.items(): if os.stat(f).st_mtime > mt: callback(f) fileMap[f] = os.stat(f).st_mtime def stakeout(callback, files): fileMap = {} signal(SIGUSR1, lambda sig, frame: trigger(callback, fileMap)) dirs = [] for f in files: fileMap[f] = os.stat(f).st_mtime d = os.path.dirname(f) if not len(d): d = "." if not d in dirs: dirs.append(d) fd = os.open(d, os.O_RDONLY) fcntl(fd, F_SETSIG, SIGUSR1) fcntl(fd, F_NOTIFY, DN_MODIFY | DN_MULTISHOT) while 1: try: pause() except KeyboardInterrupt: sys.exit(0) if __name__ == "__main__": if len(sys.argv) > 2: if "-a" in sys.argv: sys.argv = filter(lambda a: a != "-a", sys.argv) callback = lambda f: os.system("%s '%s'" % (sys.argv[1], f)) else: callback = lambda f: os.system(sys.argv[1]) stakeout(callback, sys.argv[2:]) else: print """Runs the given command when any of the files change. Usage: stakeout.py [-a] [command] [files]..." Options: -a Pass the changed file as an argument for the command.""" sys.exit(1)