libtmux Reference MCP Search

Capture pane output

Edit this page on GitHub

The other half of Attach and send keys: reading what a pane printed, and — since tmux accepts a command before the shell running it has necessarily finished (see Sending keys) — waiting for the right moment to read rather than reading immediately or sleeping a guessed amount. Capturing output is the guide-level discussion of why each pattern below exists; this page is the sourced code behind it — see the table at the end for exactly which file each block came from and how it’s checked.

Read what’s on screenLink to section

No checked .NET example calls the ordinary Pane.CaptureAsync by itself outside a wait — the README’s own read is the block under “Wait for text instead of guessing a delay” below, and the separate Psmux surface has its own CaptureAsync for that different transport (examples/LibTmux.Examples/Snippets/Psmux.cs).

const auto visible = pane.capture();
if (visible.has_value()) {
std::printf("%zu bytes on screen\n", visible->size());
}
const auto history = pane.capture({.whole_history = true});
if (history.has_value()) {
std::printf("%zu bytes of scrollback\n", history->size());
}

Wait for text instead of guessing a delayLink to section

Python’s checked wait is wait_for, tmux’s own signal channel, rather than a helper that scrapes pane text for a pattern — no checked helper that waits on pane text was found in the source for this page.

Session.OpenNotifications streams what tmux does as it happens rather than polling — tmux pushes each change instead of a poll guessing how often to ask. tmuxtest.WaitForText (see Testing with libtmux) is the equivalent built specifically for tests.

Rust’s wait_for_text looks before it sleeps, joins wrapped lines so a needle spanning a wrap still matches, and returns PaneWait::Dead rather than hanging forever if the pane’s process ends first.

Attaching a ControlClient is what makes tmux push %output at all — a client that never attaches only ever hears command replies.

TmuxWait.UntilAsync polls a read against a predicate rather than sleeping a fixed amount.

C++ has no checked snippet that waits on pane text. Server::wait_for(channel, timeout), in include/libtmux/server.hpp, uses tmux’s own wait-for signal instead of scraping output, and its doc comment explains why that is the safer choice when the command you are waiting on can be made to announce itself: “a server that dies under a waiter makes tmux exit zero, which is indistinguishable from being signalled … this reports that as a failure instead.”

waitForOutput takes patterns for both success and failure, so a process that fails fast is discovered immediately rather than by timing out.

Where this comes fromLink to section

PortSourceIn this pageChecked by
Pythonsrc/libtmux/pane.py (capture_pane), src/libtmux/server.py (wait_for) docstringshand-quotedpytest runs every >>> doctest against a real, isolated tmux session on every test run
TypeScriptexamples/capture/capture.ts (read), examples/agent/agent.ts (wait)read whole from each fileboth run against real tmux by bun test examples; agent.ts is additionally mirrored into README.md under a <!-- runs: ... --> marker checked by scripts/check-doc-runnable.ts
Goexamples/quickstart/main.go (read, already shown whole on the previous page), examples/control-mode-subscribe/main.go (wait)read: hand-quoted; wait: read whole from the fileboth run against real tmux as TestQuickstart / TestControlModeSubscribe; the wait file’s docs:watching region is additionally mirrored into README.md by go generate ./tmux
Rustcrates/libtmux/examples/scratch.rs, already shown whole on the previous pagehand-quoted excerpts of the same filerun to completion against a throwaway tmux by scripts/run-examples.sh, which CI runs
Javaroot README.md Quickstart (read), examples/src/main/java/io/github/libtmux/examples/WatchPaneOutput.java (wait)read: hand-quoted; wait: read whole from the fileevery README fence is compiled and run against real tmux by docs-tests; WatchPaneOutput is additionally run by the examples module’s ExamplesRunTest
.NETroot README.md, “Running something, and reading it back”hand-quotedone of the csharp run blocks compiled and run against real tmux by ReadmeExampleTests
C++examples/05-readme.cpp capture region (read); include/libtmux/server.hpp doc comment (wait, no fence)hand-quotedthe capture region is quoted verbatim into README.md and checked by tools/docs/check_readme.py; the whole file is built and run by CTest
SwiftExamples/Sources/ExampleCode/Changing.swift (read, already shown whole on the previous page), Waiting.swift (wait)read: hand-quoted excerpt; wait: read whole from the fileboth matched against the README by Scripts/check_examples.py and run by swift test --package-path Examples

Go, Rust, and Swift each reuse a file already shown in full on Attach and send keys: rather than dump the same file a second time, this page quotes just the relevant lines by hand, with a comment naming the source, and points back at the full listing there.

Esc

Type to search.