#!/usr/bin/python # # do-until - run a command until it succeeds # Copyright (C) 2008 Lars Wirzenius # # 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 3 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, see . """Run a command until it succeeds. Lars Wirzenius """ import optparse import subprocess import sys import time def do_until(options, argv): tries = 0 while options.max_tries == 0 or tries < options.max_tries: tries += 1 if options.verbose: sys.stderr.write("do-until: attempt #%d: %s\n" % (tries, " ".join(argv))) if options.no_act: sys.stderr.write("do-until: not running command, pretending it " "works anyway\n") break else: p = subprocess.Popen(argv) p.communicate() if p.returncode == 0: break sys.stderr.write("do-until: command failed, " "trying again in %d second(s)\n" % options.sleep) time.sleep(options.sleep) def parse_args(args): parser = optparse.OptionParser() parser.add_option("-n", "--no-act", action="store_true", help="Do not run command, just pretend to do it, and " "pretend that it succeeds.") parser.add_option("-v", "--verbose", action="store_true", help="Print command before executing it.") parser.add_option("--sleep", type="int", default=1, metavar="SECS", help="Wait SECS seconds before re-trying a command. " "(Default is %default.)") parser.add_option("--max-tries", type="int", default=0, metavar="COUNT", help="Try at most COUNT times, with 0 meaning forever. " "(Default is %default.)") options, argv = parser.parse_args(args) return options, argv def main(): try: options, argv = parse_args(sys.argv[1:]) if argv: do_until(options, argv) except KeyboardInterrupt: sys.exit(1) if __name__ == "__main__": main()