During hands-on Linux training it is useful to let a trainee follow your
terminal session live — without the risk of his accidentally typing something
that derails the demo.
tmux makes this straightforward through shared sockets and its built-in
read-only attach mode.
The problem
When demonstrating something in a terminal, a trainee sitting next to you or connected over SSH can share your screen, but he they have no keyboard control over what they see.
If they open their own terminal and you give them access to your tmux session without restrictions, they can type — which is not what you want during a demo.
What you need is a way for them to see exactly what you are doing, in their own terminal window, but in a purely passive, read-only mode.
How tmux shares sessions
tmux communicates through a Unix domain socket.
By default each user gets a private socket in /tmp/tmux-<uid>/. If
you point two tmux clients at the same socket file, both see the same
sessions and windows — just like attaching to a session from two
terminals.
The attach subcommand accepts a -r flag that opens the session in
read-only mode: the client receives all output but cannot send input.
tmux -S /path/to/socket attach -rThat is the core of the trick.
Setting up automatic socket permissions
By default tmux creates the socket with mode 600 (owner read/write only).
To let another user connect, the socket must be group-writable (664 or
660).
Rather than remembering to run chmod by hand every time, add this line to
~/.tmux.conf:
set-hook -g session-created "run 'chmod 664 #{socket_path}'"This hook fires automatically whenever a new session is created and sets the permissions on the socket, regardless of where the socket lives.
Note | Mode |
The scripts
Two small scripts wrap the workflow so neither party has to remember the socket path or the right tmux flags.
show — run this as the trainer
#!/bin/bash
SOCKDIR="/tmp/training"
SOCK="${SOCKDIR}/tmux"
rm -rf ${SOCKDIR}
mkdir -p ${SOCKDIR}
chmod g+s ${SOCKDIR} # new files inherit the directory's group
tmux -S ${SOCK}What it does:
Wipes any leftover socket directory from a previous session.
Creates a fresh directory under
/tmp/training/.Sets the setgid bit so that the socket file created inside inherits the directory’s group automatically.
Starts tmux using that socket.
The session-created hook in ~/.tmux.conf takes care of setting 664 on
the socket as soon as tmux creates it.
watch — run this as the trainee
#!/bin/bash
SOCKDIR="/tmp/training"
SOCK="${SOCKDIR}/tmux"
tmux -S ${SOCK} attach -rThe -r flag makes the session read-only.
The trainee sees everything the trainer does — including full-screen
applications like vi, less, or man — but cannot type a single character.
Usage
Trainer runs
show. A new tmux session opens in his terminal.Trainee runs
watch. He is attached to the same session, read-only.Trainer works normally. The trainee follows along in real time.
When the trainer exits tmux (or closes the session), the
watchclient detaches automatically.
Why not script or screen sharing?
script -f pipes raw terminal bytes to a file and the viewer tails it.
This works for plain shell output but breaks immediately with full-screen
applications such as vi or atop, because the cursor-movement escape
sequences render as garbage in a tail -f viewer.
tmux, by contrast, maintains a proper virtual terminal internally and sends rendered output to every attached client — so full-screen apps look exactly the same for the trainee as they do for the trainer.
Summary
| File | Purpose |
|---|---|
| Hook that chmods the socket to |
| Trainer script — creates the shared socket and starts tmux |
| Trainee script — attaches read-only to the shared session |
Three pieces, no extra software, works with any terminal application.