Bind a Macropad Key to a Shell Script on macOS

Left-Hand Pad is a twelve-key macOS macropad arranged in four columns by three rows with two rotary knobs. A hotkey daemon can connect one of its spare outputs to a carefully limited shell script.

What tool actually runs a script when a key fires?

macOS needs a bridge between a keyboard event and a process. skhd is a small hotkey daemon whose configuration executes commands through a shell. Hammerspoon creates global hotkeys in Lua and provides functions for running shell commands. Both require appropriate input or accessibility permission.

Neither tool makes an unsafe script safe. Use an uncommon macropad combination, an absolute script path and a command that can be run twice without damage. Do not embed passwords, tokens or pasted user content in the binding.

How do you set it up with skhd?

Use skhd's observe option to confirm the key and modifiers, then add a single hotkey line to its configuration pointing at the script. The daemon can reload its configuration while running. Its current repository is in maintenance mode, so read the project status and compatible alternatives before standardizing a new setup.

Secure Keyboard Entry can prevent skhd from receiving events, and its own documentation says accessibility access requires a restart after approval. Check the daemon's log when a binding fails rather than broadening permissions or changing the script simultaneously.

How do you do the same with Hammerspoon?

Hammerspoon's hs.hotkey.bind creates a global shortcut with separate pressed, released and repeated callbacks. A pressed callback can call hs.execute with a fully quoted absolute command. Its return values expose output, success and exit status, which can support a visible failure notification.

Loading the user's interactive shell environment adds overhead and can change behavior. Prefer an explicit executable path and environment inside a small wrapper script. Reload the Hammerspoon configuration, trigger a harmless logging command and inspect the result before touching a development service.

What scripts deserve a physical key?

Opening a known log, checking service status, toggling a reversible local mode or focusing a project are defensible. Restarting a development server can work if the script verifies its target and prevents overlapping runs. Deployment, deletion and commands requiring administrative credentials should remain typed and reviewed.

The Left-Hand Pad supplies enough positions for a control panel, but use labels only after repeated testing. Add a lock or cooldown for scripts that should not run twice, write timestamps to a log and keep a normal terminal command as the recovery path. Prefer a script that exits with a meaningful status, allowing the hotkey layer to report failure instead of silently pretending it worked.

Back to blog