scriptRunner will run all scripts within a folder that you specify.
April 27, 2014 ยท View on GitHub
#!/usr/bin/python
scriptRunner will run all scripts within a folder that you specify.
Useful for LaunchAgents and running multiple scripts at user login.
Thanks to Greg Neagle for an example of how to do this and Nate Walck for v1
Copyright 2014 Allister Banks (see end for Apache license blurb)
import optparse import os import subprocess import plistlib import datetime import sys import stat import logging import logging.handlers
Set your organizations reverse domain in the 'once' check file:
orgPlistString = "org.my.scriptRunnerOnce.plist"
logging.basicConfig(level=logging.WARN)
logr = logging.getLogger('scriptRunner')
handler = logging.handlers.SysLogHandler(address = '/private/var/run/syslog')
logr.addHandler(handler)
Possible ways to get called command output to syslog:
def sh(cmd):
return Popen(cmd,shell=True,stdout=PIPE,stderr=PIPE).communicate()[0]
output = (sh("/usr/local/sbin/mgmt/everyTest.sh"))
# logr.critical(sh('echo "foo"'))
logr.critical("SCRIPTRUNNER: %s", output)
TODO: - check return code from called script
- send stderr/out to (sys)log
Further:
- default wrap shell scripts with 'bash -x'? 'once' only?
- separate, permanent log(s) for called script/scriptRunner itself?
(issue is launchA can't write to /var/log, & /Users/Shared or /tmp aren't ideal)
maybe setup tee'd output to ~/Lib/Logs when subprocess calls?
def checkPermsAndRun(script): st = os.stat(script) mode = st.st_mode if script.lower().endswith(('.rb', '.py', '.sh')): # only run if executable AND everyone write access is NOT set # as explained succinctly here: http://stackoverflow.com/a/1861970 if (mode & stat.S_IXOTH) and not (mode & stat.S_IWOTH): subprocess.call(script, shell=True) else: print script + " is not executable or has bad permissions"
def main(): p = optparse.OptionParser() p.set_usage("""Usage: %prog [options]""") p.add_option('--once', '-o', dest='runOnce', help="""Directory of scripts to run only once.""") p.add_option('--every', '-e', dest='runEvery', help="""Directory of scripts to run every time.""")
options, arguments = p.parse_args()
if not (options.runOnce or options.runEvery):
print "Please choose a frequency and the path to a folder containing (1 or more) scripts"
p.print_help()
sys.exit(1)
# Check to see if passed options are a directory that exists or not
for path in (options.runOnce, options.runEvery):
if path is not None:
if not os.path.isdir(path):
sys.exit(path + " is not a directory")
if options.runEvery:
for script in os.listdir(options.runEvery):
checkPermsAndRun(os.path.join(options.runEvery, script))
if options.runOnce:
runOncePlist = os.path.expanduser("~/Library/Preferences/") + orgPlistString
try:
runOncePlistValues = plistlib.readPlist(runOncePlist)
except IOError:
runOncePlistValues = {}
for script in os.listdir(options.runOnce):
if script in runOncePlistValues:
print os.path.join(options.runOnce, script) + " already run!"
else:
checkPermsAndRun(os.path.join(options.runOnce, script))
runOncePlistValues[script] = datetime.datetime.now()
plistlib.writePlist(runOncePlistValues, runOncePlist)
if name == 'main': main()