Skip to content

Instantly share code, notes, and snippets.

@chriscorwin
Created August 8, 2017 18:02
Show Gist options
  • Save chriscorwin/142c9eac5a556ad1e4428f25d073feb4 to your computer and use it in GitHub Desktop.
Save chriscorwin/142c9eac5a556ad1e4428f25d073feb4 to your computer and use it in GitHub Desktop.
#!/bin/bash
## /*
# @usage LaunchAgentMgr <command>
#
# @description
# This script manages LaunchAgents for users running OS X.
# description@
#
# @options
# disable If the given LaunchAgent is currently loaded into launchctl, it will be
# unloaded, but the file will remain in ~/Library/LaunchAgents.
#
# enable If the given LaunchAgent exists in ~/Library/LaunchAgents it will
# be loaded into launchctl.
#
# inspect [-l] If the -l flag is used, only *loaded* LaunchAgents will be inspected.
# Without the -l flag, the up-to-date LaunchAgent plist file in the FLGitScripts
# repo will be displayed to stdout, as well as Sublime Text (if subl installed).
#
# list Shows a list of all LaunchAgent .plist files in ~/Library/LaunchAgents.
# Only com.finishline.* LaunchAgents are shown. In addition, show a list
# of all the currently running com.finishline.* LaunchAgents.
#
# load <agent> This command is used for singular loading of a com.finishline.*
# LaunchAgents. You should use the part of the file name which comes
# AFTER "com.finishline." for <agent>.
#
# unload <agent> This command is used for singular unloading of a com.finishline.*
# LaunchAgents. You should use the part of the file name which comes
# AFTER "com.finishline." for <agent>.
# options@
#
# @notes
# - When LaunchAgents are successfully loaded/unloaded via the load/unload commands, respectively,
# No output will displayed on screen. If errors occur, they will be displayed by launchctl.
# - When inspecting a LaunchAgent plist file, if the loaded version does not match the
# FLGitscripts version, LaunchAgentMgr load <agent> should be used to pull in and
# enable the up-to-date version.
# notes@
#
# @examples
# 1) LaunchAgentMgr list
# 2) LaunchAgentMgr load watch.less
# # this will load com.finishline.watch.less.plist
# 3) LaunchAgentMgr inspect watch
# # this will display all LaunchAgents in the FLGitScripts directory
# # which match the term "watch".
# 4) LaunchAgentMgr enable watch.less
# # if the com.finishline.watch.less.plist file has already been loaded into the
# # ~/Library/LaunchAgents directory, it will be loaded into launchctl if it hasn't already.
# examples@
#
# @dependencies
# gitscripts/functions/0100.bad_usage.sh
# dependencies@
#
# @file launch_agent_manager.sh
## */
if [ ! $_ENV_OSX ]; then
echo
echo "${E} Your OS does not support LaunchAgents. Exiting... ${X}"
exit
fi
$loadfuncs
echo
echo ${H1}${H1HL}${X}
echo "${H1} ${X}"
echo "${H1} Listing LaunchAgents ${X}"
echo "${H1} ${X}"
echo ${H1}${H1HL}${X}
flgs_la_path="${flgitscripts_path}launch_agents/"
user_la_path=~/Library/LaunchAgents
currentAgents=`ls -la ${user_la_path} | egrep -o 'com\.finishline\..*'`
flgsAgents=`ls -la ${flgs_la_path} | egrep -o 'com\.finishline\..*'`
loadedAgents=`launchctl list | grep com.finishline | cut -f 3`
dun="${S}done${X}"
# used to query an SSV variable for a particular value
laFind() {
if [ -z "$1" ] || [ -z "$2" ]; then
return 1
elif [ -z $"$2" ]; then
return 1
fi
str="$1"
var=${!2}
for agent in $var; do
grep $str <<< $agent
done
return 0
}
# used to display entries given in space-separated values (SSV)
displaySSV() {
for entry in $1; do
echo " $entry"
done
return 0
}
echo
case "$1" in
disable)
[ -z "$2" ] && {
__bad_usage LaunchAgentMgr "You must specify a LaunchAgent to disable!"
exit 1
}
result=`laFind "$2" loadedAgents`
[ -z "$result" ] && {
echo "${E} No matching LaunchAgents loaded which match: $2 ${X}"
exit
}
echo " ${A}Disabling${X}: "
displaySSV "$result"
echo
echo " ${I}Continue (Y/n)?${X} "
read answer
! grep -q n <<< "$answer" && {
for agent in $result; do
launchctl unload "${user_la_path}/${agent}.plist"
done
}
echo " All $dun!"
;;
enable)
[ -z "$2" ] && {
__bad_usage LaunchAgentMgr "You must specify a LaunchAgent to enable!"
exit 1
}
result=`laFind "$2" currentAgents`
[ -z "$result" ] && {
echo "${E} No matching LaunchAgents found for: $2 ${X}"
echo "${E} Try running: LaunchAgentMgr load $2 ${X}"
exit
}
echo " ${A}Loading${X}: "
displaySSV "$result"
echo
echo " ${I}Continue (Y/n)?${X} "
read answer
! grep -q n <<< "$answer" && {
for agent in $result; do
launchctl load "${user_la_path}/${agent}"
done
}
echo " All $dun!"
;;
inspect)
doLoaded=false
[ -z "$2" ] && {
__bad_usage LaunchAgentMgr "You must specify a LaunchAgent to inspect!"
exit 1
}
str="$2"
[ -n "$3" ] && {
if [ "$2" = "-l" ]; then
doLoaded=true
str="$3"
fi
}
if [ "$doLoaded" = "true" ]; then
result=`laFind "$str" loadedAgents`
agentPath="${user_la_path}/"
verb="loaded"
else
result=`laFind "$str" flgsAgents`
agentPath="$flgs_la_path"
verb="matching"
fi
[ -z "$result" ] && {
echo "${E} No ${verb} LaunchAgents to inspect for: $str ${X}"
exit
}
for agent in $result; do
! grep -q plist <<< "$agent" && agent="${agent}.plist"
echo "${A}${agent}${X}:"
echo
cat "${agentPath}${agent}"
echo
[ -n "`which subl`" ] && subl "${agentPath}${agent}"
done
;;
list)
echo " ${A}Available to Enable:${X}"
displaySSV "${currentAgents//com.finishline./}"
echo ${H2HL}${X}
echo " ${A}Available to Load:${X}"
displaySSV "${flgsAgents//com.finishline./}"
echo ${H2HL}${X}
echo " ${A}Loaded and Enabled:${X}"
displaySSV "${loadedAgents//com.finishline./}"
echo ${H2HL}${X}
;;
load)
[ -z "$2" ] && {
__bad_usage LaunchAgentMgr "You must specify a LaunchAgent to load!"
exit 1
}
str=${2//\.plist/}
result=`laFind "${str}" flgsAgents`
[ -z "$result" ] && {
echo "${E} No matching LaunchAgents found for: ${str} ${X}"
exit
}
echo " Found LaunchAgent(s) to ${A}load${X}:"
displaySSV "$result"
echo
echo " ${I}Continue (Y/n)?${X} "
read answer
grep -q n <<< "$answer" && {
echo
echo " No problemo. Goodbye!"
exit
}
echo
# first unload the agent(s) if a previous version was already loaded
loadMsg="Enabling"
isLoaded=`laFind "${str}" loadedAgents`
if [ -n "$isLoaded" ]; then
loadMsg="Re-enabling"
echo -n " One or more LaunchAgents you specified is/are loaded. ${A}Unloading${X} now..."
for agent in $isLoaded; do
launchctl unload "${user_la_path}/$agent.plist"
done
echo $dun
echo
fi
# copy launch agents
echo -n " ${A}Copying${X} LaunchAgents (${result}) to ~/Library/LaunchAgents..."
for agent in $result; do
cp -fR "${flgs_la_path}${agent}" "${user_la_path}/$agent"
done
echo $dun
echo
echo " ${A}${loadMsg}${X}: "
displaySSV "$result"
echo
echo " ${I}Continue (Y/n)?${X} "
read answer
! grep -q n <<< "$answer" && {
for agent in $result; do
launchctl load "${user_la_path}/${agent}"
done
}
echo " All $dun!"
;;
unload)
[ -z "$2" ] && {
__bad_usage LaunchAgentMgr "You must specify a LaunchAgent to load!"
exit 1
}
result=`laFind "$2" loadedAgents`
result2=`laFind "$2" currentAgents`
# if the files arent in the user's LaunchAgents folder, then they aren't loaded
[ -z "$result2" ] && {
echo "${E} No matching LaunchAgents to unload for: $2"
exit
}
echo " ${A}Unloading${X}: "
displaySSV "$result2"
echo
echo " Continue (Y/n)?"
read answer
! grep -q n <<< "$answer" && {
for agent in $result2; do
grep -q "${agent%.plist}" <<< "$loadedAgents" && {
launchctl unload "${user_la_path}/${agent}"
}
rm -Rf "${user_la_path}/${agent}" && echo " ${A}Unloaded${X} ${agent}"
done
}
echo " All $dun!"
;;
*)
__bad_usage LaunchAgentMgr "Invalid command given to LaunchAgentMgr."
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment