Capturing output
Reading what a pane printed is the other half of the round trip Sending keys covers the first half of. Two questions come up every time: how much of the pane do you get back, and how do you know when the thing you’re waiting for has actually appeared?
Visible pane vs. scrollbackLink to section
tmux capture-pane distinguishes the currently visible screen from the
scrollback history above it, and every port exposes that split rather than
flattening it:
# 0 is the first visible line; positive numbers stay in the visible pane;# negative numbers reach into history; "-" means "the start of the# history." With no arguments you get the visible screen.>>> pane = window.split(shell='sh')>>> pane.capture_pane()['$']Java’s pane.capture() and .NET’s pane.CaptureAsync() return the visible
pane as a list of lines; neither’s own README shows a scrollback option as
of this page, so check the port’s reference before assuming one exists.
Sources: TypeScript’s is examples/capture/capture.ts, run by bun test examples/capture. Go’s is examples/quickstart/main.go. Rust’s is
crates/libtmux/README.md’s capability table, doctested via #![doc = include_str!("../README.md")]. C++‘s is README.md’s “Read a pane”
section, quoted verbatim from examples/05-readme.cpp’s capture region
and checked by tools/docs/check_readme.py. Swift’s is README.md,
“Change what is there.”
Don’t poll — wait for the text insteadLink to section
Reading a pane the instant after you send to it races the shell, as
Sending keys
covers. A fixed sleep “fixes” this by guessing a delay that’s either too
short (flaky) or too long (slow) — every port that takes testing or
automation seriously ships something better:
Python’s own pytest plugin gives tests a real, isolated server (see
Testing with libtmux), but a documented
wait-for-text helper for ordinary, non-test code wasn’t found in the checked
source for this page — server.wait_for(...), below, covers the adjacent
“wait for a signal” case. C++ has no equivalent poll-for-text helper either;
its own wait primitive is the signal channel covered next.
Sources: Go’s is tmux/tmuxtest/screen.go, quoted in README.md’s “Testing
your own code” section. Rust’s is crates/libtmux/README.md, doctested.
TypeScript’s is examples/agent/agent.ts, run by the integration suite and
quoted in packages/libtmux/README.md (<!-- runs: examples/agent/agent.ts -->). Java’s is examples/.../WatchPaneOutput.java. .NET’s is README.md,
one of the csharp run blocks ReadmeExampleTests runs. Swift’s is
Examples/Sources/ExampleCode/Waiting.swift, matched against
<doc:Waiting> and the README by Scripts/check_examples.py; the same
file’s server.capture(pane, since: mark), called in a loop with the cursor
it returns, is the “watch as it prints” shape for output too large or too
open-ended to wait on a single pattern.
When the pane can announce itself: wait-for, not scrapingLink to section
If the command you’re running can be made to say when it’s done — appending
; tmux wait-for -S done to it, say — several ports expose tmux’s own
signal-channel primitive directly, which needs no text matching at all:
>>> server.new_session(session_name='wait_test')Session(...)>>> server.wait_for('test_channel', set_flag=True)Verified doctest, src/libtmux/server.py. C++‘s Server::wait_for(channel, timeout) is the same idea, with a specific reason to prefer it over
scraping output for a marker: “a server that dies under a waiter makes tmux
exit zero, which is indistinguishable from being signalled — a caller
would carry on as though the other side had spoken. This reports that as a
failure instead” (source: include/libtmux/server.hpp). Swift’s
server.wait(for:) channel example runs a build and blocks on its own
completion signal rather than watching for text to scroll by:
Source: Examples/Sources/ExampleCode/Waiting.swift. Rust’s
crates/libtmux/README.md documents the same pattern under “tmux keeps a
signal nobody is waiting on, so the job finishing first does not lose the
race, and nothing polls,” runnable as examples/orchestrate.rs.
Where to go nextLink to section
- Filtering and querying, in practice — once you’re reading more than one pane, finding the right one to capture.
- Testing with libtmux — the isolated-server fixtures that make waiting on real tmux practical inside a test suite.
- Capture pane output — the full sourced code for the patterns above.