---
title: 'Example: Writing a Launch Agent for Apple''s launchd'
teaser: Using launch agents to periodically perform user tasks.
tags: osx
author: Adarsh Pandit
published_on: 2012-09-26
---

Clutter in programmer workspaces, whether digital or physical, can add a mental
cost. An area of common clutter is the `~/Downloads` directory in Mac OS X. I
want to clean it up ... programmatically.

## The Goal

I want a background job to find files in `~/Downloads` which haven't been
modified within the past week and move them into `~/.Trash`.

In zsh, the command for this is: `mv ~/Downloads/*(mw+1) ~/.Trash`.

Read `man zshexpn` for more awesomeness on shell expansion.

## Launch Agents

For a user-specific background job, [Apple recommends creating a Launch
Agent][apple], which is a `.plist` <abbr title="Extensible Markup
Language">XML</abbr> file located in `~/Library/LaunchAgents`.

[apple]: http://bit.ly/designing-daemons-and-services

The `~/Library/LaunchAgents/com.thoughtbot.cleandownloads.plist` file will run
my script once an hour:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>com.thoughtbot.cleandownloads</string>
  <key>ProgramArguments</key>
  <array>
    <string>mv</string>
    <string>~/Downloads/*(mw+1) ~/.Trash</string>
  </array>
  <key>StartCalendarInterval</key>
  <dict>
    <key>Hour</key>
    <integer>1</integer>
  </dict>
</dict>
</plist>
```

Read [Creating Launch Daemons and Agents][creating] for more on how to structure
the `.plist` file.

[creating]: http://bit.ly/creating-launch-daemons-and-agents
