bunkdeck!!
bunkdeck
is a terminal ~application suite~ that we made so it would be easier to talk to each other on our tilde server. this is her story...
IMAGINE you've found yourself in this position: you've recently started a computer club (!!!! https://startacomputer.club !!!!) with some friends. you're engaged in the project of improving the political economy of computing in the place that you live. and you want to have some fun and do some skillsharing while you do it. so you (maren) set up a tilde server and invite your friends (sorrel & [names redacted]). now that you've got some shared computing resources, what sorts of things do you get up to?
one of the things we got up to was a simple chat application. we wanted something dramatically simpler than irc — you just ssh into the tilde server and write your texts to a file and read other texts from the file and everything is beautiful. so how did we do that? first was...
proclaim
proclaim
is the program (part of the greater bunkdeck ~application suite~) for posting messages in the groupchat. it looks like a regular text box that you type words into and press ENTER to post them. here's the code:
#!/bin/bash -e
# make username uppercase
username=$(echo "$USER" | tr '[:lower:]' '[:upper:]')
timezone="America/New_York"
declare prompt
makeSlug () {
# make time and date
time=$(TZ=${timezone} date +%I:%M%p)
date=$(TZ=${timezone} date +%m/%d)
# make name/time string
prompt="${username}-${date}-${time}"
}
# enter bunkchat mode (clear the screen)
clear
while true
do
figlet -f future proclaim - bunkchat
echo "You may view old chat with 'scry', heathen."
echo "-------------------------------------------"
read -r -p "speak to the server: " text
makeSlug
echo "${prompt}: $text" >> /srv/bunkchat.txt
clear
done
proclaim is just a bash read
loop accepting input from the user. when the user presses enter
, it appends what they typed to the chat file bunkchat.txt
, then clears the screen and sets a clean read prompt and waits again.
for a long time, proclaim
didn't have timestamps. the makeSlug()
function didn't exist, and each post slug was just the username of the person who posted.
when we decided we wanted to know what time someone made a post, we implemented an unrelated cron job. this made an ASCII rooster (courtesy of cowsay
) announce the time in chat every fifteen minutes. it was hilarious at first, but made reading old chat annoying because there was inevitably more rooster than chat.
heed
heed
is the program (part of the greater bunkdeck ~application suite~) that displays chats to a bunkdeck user. it has a banner and looks like a textfield. when new posts are made, they automatically show up at the bottom of that textfield. here's the code:
#!/bin/sh -e
clear
figlet -f future heed - bunkchat
echo "#######################################################################"
echo "# Take heed, $USER! This is a group chat with everyone on the server! #"
echo "# You can view earlier chat with 'scry' or 'less /srv/bunkchat.txt' #"
echo "#######################################################################"
echo
tail -f /srv/bunkchat.txt
heed is even simpler than proclaim! it's literally just tail
ing the chat file bunkchat.txt
(with just a little bit of style.) incredible!
heed is so simple it has remained unchanged since its original implementation. there was still a problem, however. running proclaim and running heed required bunkchatters to either open two ssh tunnels into our server OR have enough familiarity with terminal multiplexing to run them both in one session.
enter...
bunkdeck
bunkdeck
is the ~suite~ part of the bunkdeck ~application suite~ that runs proclaim
and heed
in a single terminal AND gives you a shell to hack away with while you chat with your computational comrades. the code is as follows.. ..
actually, it's too long to put in this blog post, so you should just look at it here. as a teaser, here's one of her functions:
#!/bin/bash
set -e
# ...
heedPane="bunkdeck:0.0"
proclaimPane="bunkdeck:0.1"
shellPane="bunkdeck:0.2"
# ...
function startNewDeck {
tmux new -d -s bunkdeck heed
tmux split-window -h -t bunkdeck -p 70
tmux split-window -t $heedPane -v -p 3
tmux send-keys -t $proclaimPane 'proclaim' C-m
tmux send-keys -t $shellPane 'cowsay "press [CTRL+b then o] to cycle through panes"' C-m
# turn on pane titling
tmux select-pane -t $heedPane -T heed
tmux select-pane -t $proclaimPane -T proclaim
tmux select-pane -t $shellPane -T shell
tmux set -g set-titles on
# attach session to shell
tmux attach -t $shellPane
}
bunkdeck is just tmux with some little conveniences. it started its life as a couple lines to start a new tmux session, split the window into a few panes and run heed
and proclaim
appropriately. when bunkchatters who were new to tmux ran bunkdeck
they found themselves uncertain of how to navigate around, so we enlisted a helpful cow to say “press [CTRL+b then o] to cycle through panes.” (did you know you can press [CTRL+b then o] to cycle through panes?). for a while, this caused a hilarious bug that caused all of us to post “press [CTRL+b then o] to cycle through panes.” repeatedly in the chat. so now we just yell that at each other sometimes
one of the nice things about tmux is that sessions can persist indefinitely. so, a bunkchatter could ssh into our little tilde server, start a bunkdeck session, and then leave (by choice or for wont of internet infrastructure) secure in the knowledge that they could later re-attach to the session and rejoin the chat.
sort of. it turns out tmux got weird if you try to run this original version of bunkdeck while there is already a bunkdeck session running. so! let's check for an existing bunkdeck session and attach to it if there is one. no problem! tmux lets you do that; you just need a little error-guarding:
function isExistingDeck {
set +e
sessions=$(tmux list-sessions)
set -e
if [[ $sessions == *"bunkdeck"* ]]; then
return 0
else
return 1
fi
}
this was before we split things up into functions mind you. you can see what the file looked like at this point here. after breaking up our script into functions, it was much easier to add small quality of life features, and the code is also easier to understand now
one of the quality of life features is taking the life of a bunkdeck session with the kill
command which we added here. another is resizing tmux panes with user-friendly commands (grow
& shrink
) that abstract tmux's resize-pane
flags (-D
-U
-L
-R
).
other thoughts about tilde chatting
none of us have used other tilde servers much, so we don't know how they do chat. we're really happy with what we came up with, but it has a caveat — we could only do chat this way because we all know and trust each other. without that, it wouldn't have been safe to make files world writeable and readable, and proclaim and heed rely on that. most of our little tools are built on this kind of trust <3