Hooks, pipe-pane, wait-for and control mode

tmux · Expert · 12 min

These features turn tmux into an automation platform and explain how terminals like iTerm2 integrate with it.

Hooks run a command when an event happens: set-hook -g after-split-window 'select-layout even-horizontal', or set-hook -g client-attached 'display "welcome back"'. Hooks exist for most commands (after-<command>) and for events such as session-created, pane-exited, client-detached. show-hooks -g lists them; hooks are arrays, so set-hook -ga appends.

pipe-pane sends everything a pane outputs to a shell command: pipe-pane -o 'cat >> ~/pane.log' starts logging (the -o makes the same binding toggle it off again). Output includes raw escape sequences.

wait-for gives scripts a simple channel-based synchronisation: tmux wait-for build-done blocks until some other command runs tmux wait-for -S build-done. Combined with send-keys, a script can start a command in a pane and wait for it to finish.

Control mode (tmux -C, or -CC which also disables echo for terminals) replaces the drawn screen with a text protocol: commands go in, output comes back wrapped in %begin / %end blocks, and asynchronous notifications such as %output %1 ..., %window-add @3 stream out. iTerm2's tmux integration uses it to show tmux windows as native tabs, and it is a robust way to build tools that watch tmux without screen scraping.

Example

# keep splits even automatically
tmux set-hook -g after-split-window 'select-layout even-horizontal'
# toggle logging the current pane to a file
tmux bind P pipe-pane -o 'cat >> ~/tmux-#{pane_id}.log' \; display 'logging toggled'
# run a build in another pane and wait for it
tmux send-keys -t dev:run 'make; tmux wait-for -S built' Enter
tmux wait-for built && echo "build finished"
# control mode: talk to tmux as a protocol
printf 'list-windows\n' | tmux -C attach -t dev
# %session-changed $0 dev
# %begin 1792223274 292 1
# 0: editor (1 panes) [80x24] ...
# %end 1792223274 292 1

Remember

  • set-hook runs commands on events like after-new-window or pane-exited
  • pipe-pane -o toggles logging a pane's output
  • wait-for -S / wait-for synchronise scripts; -C is a machine-readable protocol

Watch out for

  • Forgetting pipe-pane output contains escape sequences; strip them before grepping the log.

Check yourself

  1. How can a shell script block until a command typed into another pane has finished?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: man.openbsd.org/tmux.1#HOOKS