# How to Use Pre/Post Hooks When Switching MongoDB Versions with m

> Automate MongoDB version changes with m pre/post hooks. Execute custom scripts for setup and teardown tasks seamlessly.

- Repository: [Aaron Heckmann/m](https://github.com/aheckmann/m)
- Tags: how-to-guide
- Published: 2026-02-23

---

**m supports pre and post hooks that execute custom scripts automatically when you install or change MongoDB versions, enabling automation of setup and teardown tasks.**

The `m` version manager for MongoDB (maintained in the `aheckmann/m` repository) provides a powerful hook system that runs arbitrary executable scripts at specific lifecycle events. This allows you to automate tasks like stopping services before a version switch or starting them afterward.

## Understanding Pre and Post Hooks in m

Hooks in `m` are executable scripts registered to run either **before** (pre) or **after** (post) specific events. The system supports two primary events:

- **install** – Triggered when a new MongoDB version is downloaded and installed
- **change** – Triggered when switching the active MongoDB version (creating symlinks)

When registered, `m` stores the absolute path to your script in plain-text files located in the internal data directory (`$M_DIR`, defaulting to `~/.local/m`). Hook files follow the naming convention `pre_<event>` and `post_<event>` (for example, `pre_change` or `post_install`).

## Registering Hooks with m pre and m post Commands

The `install_hook` function in `bin/m` (lines 1735–1765) handles hook registration. When you run `m pre <event> <script>` or `m post <event> <script>`, `m` validates that the script path is absolute and executable before writing it to the hook file.

### Hook Events and Validation

Valid events are strictly `install` or `change`. The system validates:

- The script path must be **absolute** (not relative)
- The script must have **executable permissions**
- Duplicate entries are automatically ignored

### Storage Location

Hook files reside in `$M_DIR`, which derives from the `M_PREFIX` environment variable (default: `$HOME/.local/m`). A typical hook file path looks like `~/.local/m/pre_change`.

## How Hooks Execute During Version Switches

Hook execution occurs at specific points in the version activation flow defined in `bin/m`. The `pre()` and `post()` functions (lines 1812–1820 and 1826–1834) read their respective hook files line-by-line and execute each script.

### Execution Points in the Activation Flow

When switching versions, `m` triggers hooks at these exact locations:

- **Line 986**: `pre change` runs immediately before creating symlinks to the new version
- **Line 995**: `post change` runs immediately after the symlinks are created

The same pattern applies to the `install` event, allowing you to run scripts before and after downloading and extracting a MongoDB binary.

## Managing and Removing Hooks

The hook system provides commands to list and remove registered scripts.

### Listing Registered Hooks

Run `m pre <event>` or `m post <event>` without specifying a script to display all registered hooks for that event. The `list_pres` and `list_posts` helper functions read and display the contents of the hook files.

### Removing Hooks

Remove hooks using the `rm` keyword:

```bash

# Remove a specific post-change hook

m post change rm /home/user/scripts/cleanup.sh

# Remove all pre-install hooks

m pre install rm

```

The removal logic (lines 1756–1773 in `bin/m`) rewrites the hook file, skipping any line matching the target script path.

## Practical Examples

Here are complete examples for automating MongoDB version switches with hooks.

### Stopping Services Before Switching

Create a pre-change hook to gracefully stop `mongod` before the version changes:

```bash
#!/usr/bin/env bash

# /home/user/scripts/stop-mongod.sh

pkill -f mongod && echo "mongod stopped"

```

Register it:

```bash
chmod +x /home/user/scripts/stop-mongod.sh
m pre change /home/user/scripts/stop-mongod.sh

```

### Starting Services After Switching

Create a post-change hook to start the new version:

```bash
#!/usr/bin/env bash

# /home/user/scripts/start-mongod.sh

"$M_BIN_DIR/mongod" --dbpath /data/db --fork --logpath /var/log/mongod.log

```

Register it:

```bash
chmod +x /home/user/scripts/start-mongod.sh
m post change /home/user/scripts/start-mongod.sh

```

### Automating Installation Cleanup

Add a post-install hook to remove downloaded archives after installation:

```bash
#!/usr/bin/env bash

# /home/user/scripts/cleanup-install.sh

rm -f "$M_DIR/mongodb-*.tgz"
echo "Cleaned up installation archives"

```

```bash
chmod +x /home/user/scripts/cleanup-install.sh
m post install /home/user/scripts/cleanup-install.sh

```

## Summary

- **m** provides pre and post hooks for the `install` and `change` events, allowing automatic script execution during MongoDB version management.
- Register hooks using `m pre <event> <script>` or `m post <event> <script>`; scripts must be absolute paths with executable permissions.
- Hooks execute at specific points in `bin/m`: `pre change` runs at line 986 before symlinking, and `post change` runs at line 995 after symlinking.
- Store hooks in `$M_DIR` (default `~/.local/m`) in files named `pre_<event>` and `post_<event>`.
- Manage hooks by listing (`m pre <event>`) or removing (`m pre <event> rm <script>`) entries.

## Frequently Asked Questions

### What events support pre and post hooks in m?

m supports hooks for two events: **install** (triggered when downloading and installing a new MongoDB version) and **change** (triggered when switching the active MongoDB version). You can register both pre and post hooks for either event using `m pre <event> <script>` or `m post <event> <script>`.

### Where does m store registered hook scripts?

m stores hook definitions in plain-text files inside the `$M_DIR` directory, which defaults to `~/.local/m` unless overridden by the `M_PREFIX` environment variable. Each event gets two files: `pre_<event>` and `post_<event>` (for example, `pre_change` and `post_change`). These files contain absolute paths to the executable scripts, one per line.

### How do I remove a specific hook without deleting all of them?

To remove a specific hook, run `m pre <event> rm <script>` or `m post <event> rm <script>`, replacing `<script>` with the exact absolute path of the script you want to remove. If you want to clear all hooks for an event, use `m pre <event> rm` or `m post <event> rm` without specifying a script path. The removal logic rewrites the hook file, excluding the targeted entry.

### Can I use relative paths when registering hook scripts?

No, m requires absolute paths when registering hooks. The `install_hook` function in `bin/m` validates that the provided script path is absolute and that the file has executable permissions before writing it to the hook file. If you provide a relative path, the registration will fail. Always use the full path (e.g., [`/home/user/scripts/hook.sh`](https://github.com/aheckmann/m/blob/main//home/user/scripts/hook.sh) rather than [`./hook.sh`](https://github.com/aheckmann/m/blob/main/./hook.sh)).