Server.snapshot
Source and package
- Qualified name
-
libtmux.Server: snapshot - Module
- libtmux
- Declared in
Server- Package
- libtmux
- Source
- lua/libtmux/_internal/server.lua
- Other languages
- Perlmethod Erlangfunction PowerShellcmdlet Juliafunction Elixirfunction Haskell Common Lispfunction Python RubyTypeScriptRustmethod GoJavaC# C++ SwiftKotlinScalaOCamlfunction F#function Clojurefunction
- snapshot: fun( self: libtmux
.Server , options?: libtmux.Snapshot , ):libtmuxOptions .Request <libtmux.Snapshot > -
Examples#
List sessions, windows, and panes from one captured server snapshot. Use Lua 5.1 or newer with LuaRocks, tmux 3.3a or newer, and a C compiler and CMake for luv on Linux. In a new directory, install the library and its standalone runtime dependency from LuaRocks:
Terminal window $ luarocks --tree ./rocks install luv &&luarocks --tree ./rocks install libtmux &&eval "$(luarocks --tree ./rocks path)"Save this complete launcher as
run.sh. It starts a private tmux daemon and cleans up after success or failure. A failed daemon shutdown reports and retains its socket directory. View source#!/bin/shset -euprogram=${1:?Pass the complete Lua example filename}binary=$(command -v "${TMUX_BIN:-tmux}")case "$binary" in/*) ;;*) printf '%s\n' 'tmux must resolve to an absolute path' >&2; exit 1 ;;esac# The check that a server stopped connects to its socket, which takes perl.command -v perl >/dev/null 2>&1 || { printf '%s\n' 'perl is required to confirm that tmux stopped' >&2; exit 1; }# A socket path must fit sun_path, 104 bytes on macOS. The longest path under# the directory is the default socket of a program that forgets -S, so a TMPDIR# that leaves no room for it gives way to /tmp.root=${TMPDIR:-/tmp}longest="/libtmux-lua-api.XXXXXX/tmux-$(id -u)/default"bytes=$(printf '%s%s' "$root" "$longest" | wc -c)if [ $((bytes)) -gt 100 ]; thenprintf '%s\n' 'TMPDIR is too long for a tmux socket path; using /tmp' >&2root=/tmpfidirectory=$(mktemp -d "$root/libtmux-lua-api.XXXXXX")socket="$directory/tmux.sock"# Succeeds only when a connection to the socket is refused or its path is gone.# Any other outcome leaves a server unproven stopped, including one that a tmux# client could not talk to.gone() {probed=0perl -MSocket -e 'socket(my $s, PF_UNIX, SOCK_STREAM, 0) or exit 0;connect($s, sockaddr_un($ARGV[0])) and exit 0;exit(($!{ECONNREFUSED} || $!{ENOENT} || $!{ENOTSOCK}) ? 1 : 0)' "$1" || probed=$?[ "$probed" -eq 1 ]}# Stops the server on a socket, then connects until nothing answers: a server# leaves a moment after kill-server returns. The client runs in the background# because it waits for a reply, which a server that never answers does not send.stop() {"$binary" -S "$1" kill-server >/dev/null 2>&1 &client=$!tries=0until gone "$1"; dotries=$((tries + 1))if [ "$tries" -ge 30 ]; thenkill "$client" 2>/dev/null || truewait "$client" 2>/dev/null || truereturn 1fisleep 0.1donewait "$client" 2>/dev/null || true}cleanup() {status=$?trap - 0 HUP INT TERMkept=0# A socket anywhere in the directory is a server to stop. Any but the# launcher's own is one the program started.sockets=$(find "$directory" -type s 2>/dev/null || true)while IFS= read -r found; do[ -n "$found" ] || continuename=${found#"$directory"/}if [ "$found" != "$socket" ]; thenprintf 'The program left a tmux socket in the run directory: %s\n' "$name" >&2[ "$status" -ne 0 ] || status=1fiif ! stop "$found"; thenprintf 'tmux still answers at %s\n' "$name" >&2kept=1fidone <<SOCKETS$socketsSOCKETSif [ "$kept" -ne 0 ]; thenprintf 'Cannot stop tmux; kept %s\n' "${directory##*/}" >&2exit 1firm -rf "$directory" || exit 1exit "$status"}trap cleanup 0trap 'exit 1' HUP INT TERMunset TMUX TMUX_PANE LIBTMUX_SOCKET LIBTMUX_SOCKET_PATH LIBTMUX_SOCKET_NAMEexport TMUX_BIN="$binary" TMUX_SOCKET="$socket" TMUX_TMPDIR="$directory" ENV=/dev/null BASH_ENV=/dev/null"$binary" -S "$socket" -f /dev/null new-session -d -s bootstrap -n bootstrap /bin/cat"${LUA_BIN:-lua}" "$program""$binary" -S "$socket" has-session -t '=bootstrap'Save the complete program as
snapshot.lua. Closing the library connection leaves the daemon running; the launcher owns its lifetime. View sourcelocal adapter = require("libtmux.runtime.luv")local function must(value, err)if err ~= nil thenerror(tostring(err), 0)endreturn valueendlocal binary = assert(os.getenv("TMUX_BIN"), "set TMUX_BIN to an absolute tmux executable")local socket = assert(os.getenv("TMUX_SOCKET"), "set TMUX_SOCKET to the private socket")must(adapter.run(function(runtime)local server = must(runtime:connect({ binary = binary, socket_path = socket }):await())must(server:new_session({name = "demo",window_name = "main",argv = { "/bin/cat" },}):await())local snapshot = must(server:snapshot({ strict = true }):await())local sessions, windows = {}, {}for _, session in ipairs(snapshot.sessions) dosessions[#sessions + 1] = session.nameendfor _, window in ipairs(snapshot.windows) dowindows[#windows + 1] = window.nameendtable.sort(sessions)table.sort(windows)assert(#snapshot.sessions == 2 and #snapshot.windows == 2 and #snapshot.panes == 2)print("sessions: " .. table.concat(sessions, ", "))print("windows: " .. table.concat(windows, ", "))print("panes: " .. #snapshot.panes)must(server:close():await())return trueend))Run the saved files. Assertions and operation errors produce a failing exit status:
Terminal window $ eval "$(luarocks --tree ./rocks path)" &&sh run.sh snapshot.lua- Parameters
tmux command#
The tmux commands behind snapshot.
list-buffers list-clients list-panes -a server scope, cmd_list_panes_server list-sessions list-windows -a server scope, cmd_list_windows_exec tmux C API#
The C declarations in tmux that implement these commands.
Guides#
Pages that discuss snapshot.
In other ports#
Capture the tmux hierarchy
| Language | Equivalent |
|---|---|
| Python | no equivalent on Server |
| Ruby | Lib |
| PowerShell | Lib Acquires a replacement LibTmux.Server to -Depth (panes by default). Acquisition is not atomic; retained handles do not refresh. |
| Julia | Lib Acquires a new Snapshot over an observation interval. Topology checks do not make it a transaction; earlier snapshots do not refresh. |
| Erlang | tmux Captures a new graph over an observation interval. Retained snapshots never refresh. |
| Elixir | Lib Captures a new graph over an observation interval. A retained Snapshot never refreshes. |
| Haskell | No public Haskell equivalent is implemented; the current modules expose scalar values and version parsing. |
| Common Lisp | libtmux: fetch-snapshot acquires a new interval observation. Retained snapshots never refresh in place. |
| TypeScript | server |
| Rust | server Fetches the whole hierarchy with list-sessions, list-windows -a and list-panes -a, and stitches the rows by winlink. The three listings are separate commands, so the capture is not an atomic transaction. |
| Go | tmux |
| Java | io |
| Clojure | libtmux Acquires a captured graph of persistent values. Retained values do not refresh after mutation or close. |
| Kotlin | io |
| Scala | io |
| C# | Lib |
| F# | Lib Acquires a replacement shared .NET LibTmux.Server to the requested depth. Acquisition is not atomic; retained handles do not refresh. |
| C++ | no equivalent on Server: sessions, windows, panes and clients each take a snapshot of one listing, and Snapshot::take needs the internal detail::Backend, so no public call reads the whole hierarchy at once |
| Swift | Server |
| OCaml | Libtmux Acquires a complete immutable graph over an interval. Earlier observations remain readable without refreshing. |
| Perl | Lib Strict acquisition observes an interval, not an atomic transaction; retained handles do not refresh. |