Terminal read-only live sharing
Published:
Updated:
Live sharing a terminal session to another (shared) host over SSH in read-only mode.
Update: 2017-05-06 add broadcastting over the web with node-webterm
TLDR
#!/bin/sh
host="$1"
file=script.log
touch "$file"
tail -f $file | ssh $host 'cat > script.log' &
script -f "$file"
kill %1
ssh $host "rm $file"
rm "$file"
Using screen
screen
can save the content of the screen session on a file. This is enabled with the following screen
commands:
logfile screen.log
logfile flush 0
log on
The logfile flush 0
command removes the buffering delay in screen
in order to reduce the latency.
We can watch the session locally (from another terminal) with:
tail -f screen.log
This might produce some garbage if the original and target terminals are not compatible (echo $TERM
is different) or if the terminal sizes are different:
- the first problem can be fixed by watching the log file from another
screen
; - the second problem can be fixed by agreeing on the terminal size (
xterm -geometry 90x40
,xfce4-terminal --geometry 90x40
, etc.).
Instead of watching it locally, we want to send the content to another (shared) host over SSH:
tail -f screen.log | ssh $server 'cat > /tmp/logfile'
Other users can now watch the session on the remote host with:
tail -f screen.log
Using xterm
You can create a log file from xterm
:
xterm -l -lf xterm.log
The rest of the technique applies the same.
Best viewed from a xterm
-compatible terminal.
Using script
script
can be used to create a log file as well:
script -f script.log
Downsides
The downside is that a log file is created on both the local and server-side. This file might grow (especially if you broadcast nyancat
😺 for a long time) and might need to be cleaned up afterwards.
A FIFO might be used instead of a log file with some programs. It works with screen
and script
but not with xterm
. However, I experienced quite a few broken pipes (and associated brokeness) when trying to use this method. Moreover, using a FIFO can probably stall some terminals if the consumer does not consume the data fast enough.
Broadcast service
In order to avoid the remote log file, a solution is to setup a terminal broadcast service. A local terminal broadcast service can be set up with:
socat UNIX-LISTEN:script.socket,fork SYSTEM:'tail -f script.log'
And we can watch it with:
socat STDIO UNIX-CONNECT:script.socket
We can expose this service to a remote host over SSH:
ssh $server -R script.socket:script.socket -N
The downside of this approach is that the content is transfered over SSH once per viewer instead of only once.
Web broadcast
node-webterm
can be used to broadcast the log over HTTP:
{
"login": "tail -f script.log",
"port": 3000,
"interface": "127.0.0.1",
"input": true
}
This displays the terminal in the browser using terminal.js
, a JavaScript xterm
-compatible terminal emulator (executing client-side). The default terminal size is the same as the default xterm
size. It can be configured in index.html
.
Alternatives
- ttyd, not tested