Bash script automation in macOS
Scheduling bash scripts to be run at login using `launchd`
3 min read
Photo by Lucas Hoang on Unsplash
There are many scenarios in which bash scripts can be used to automate processes. Sometimes, I like to test things in Python. For instance, sometimes one of my colleagues asks me if something is possible in Python or how it is done. In those cases, I don't want to create a new project, but rather to create a new folder, throw a bunch of python files in, and figure out things. After some time, these test projects make a big mess in my directories, which I don't like.
To fix this, I made a bash script to remove all the files and folders that I have created under "temp" every time I boot my Mac. This blog post will describe how I managed to use macOS
launchd to schedule a bash script to delete all the test files and folders.
As a Linux user or at least someone who has worked with Linux, you may be familiar with
launchd is exactly the same, but it can do more like a job scheduler (corn replacement) and it is much more reliable than
1. How to interface
Anyhow, to interact with Launchd, use
launchctl in your bash shell. Same as the
systemd and the
systemctl commands, isn't it? You can see more information about
launchctl by typing
man launchctl in your terminal window.
launchd configuration files look like?
Having learned about the concept of
launchd and its interface
launchctl, it is now time to understand how we can define a new configuration for this. In contrast to
systemd, which uses TOML config files,
launchd makes use of
plist files to define a configuration. Below is an example:
<plist version="1.0"> <dict> <key>Label</key> <string>com.example.hello</string> <key>ProgramArguments</key> <array> <string>hello</string> <string>world</string> </array> <key>KeepAlive</key> <true/> </dict> </plist>
3. Where to save
launchd configuration files?
There are three locations in which you can store a
launchd configuration file. If your application is supposed to run as a daemon service, you can store it under
/System/Library/LaunchDaemons/. If your application is supposed to run whenever a user logs in, you should store it under
/Library/LaunchAgents. Finally, If your application is supposed to run whenever a specific user logged in it must be stored under
Creating the automation
It's time to set up the automation now that we know how
launchd works. Let's create the bash script file first:
rm -rf $HOME/projects/temp && mkdir $HOME/projects/temp
You need to save this script to
~/.scripts/loginscript.sh. The script will delete the files and folders in the
temp folder every time you run it. We will now need to create the config file for Launchd so the script runs every time we log in.
<plist version="1.0"> <dict> <key>Label</key> <string>com.user.loginscript</string> <key>ProgramArguments</key> <array> <string>/bin/zsh</string> <string>PATH-TO-HOME-DIRECTORY/.scripts/loginscript.sh</string> </array> <key>RunAtLoad</key> <true/> </dict> </plist>
Let's save this to
~/Library/LaunchAgents/com.user.loginscript.plist. Before registering it to
launchd we first need to get the user id as it needs by
Copy the output and run the command below to register the configuration to
sudo launchctl bootstrap gui/<USER-ID> ~/Library/LaunchAgents/com.user.loginscript.plist