Home > Programming, tmux > tmux techniques by example

tmux techniques by example

I am a big fan of tmux – a terminal multiplexer. Think of it as a text version of vnc client, with many more powerful features. In this post I will demo some of the tmux techniques that I use quite often.

Assumptions:

1) GNU version of tmux
2) Default shell is BASH

Preparation:

For demo’s purpose I make up a dummytask.sh to simulate the task(s) that we will be running in tmux windows:

#!/bin/bash
taskname=$@
ans=''
if [ -n "$taskname" ]; then
	while [ ! "$ans" == "q" -a ! "$ans" == "Q" ]; do
		read -e -n 1 -p "Running task $taskname, to exit, press q(Q). " ans
	done
	echo "Done task $taskname."
else
	echo "Usage: $0 task."
	echo "Example1: $0 debugging"
	echo "Example2: $0 importing data"
fi
Example: create a tmux session with session name mysess
tmux new-session -s mysess -d

If the option -d (detached) is omitted, you will be taken directly to the first window titled “0:bash” once the command is executed and any commands afterwards will be entered into that window. Therefore it’s a good habit to use option -d whenever creating a new session.

Example: create a new tmux session and change the first default window title to task1

[ type q, Enter, exit, Enter if the sess tmux session is currently attached ]
In the first example, tmux will create a first window titled “0:bash” (could be ksh, csh etc depending on default shell setting) by default, to change to something else, simply using -n (name) option:

tmux new-session -s sess -d -n task1
Example: create tmux session mysess if it has not been created yet
tmux list-session 2>&1 | grep -q "^mysess:" || tmux new-session -s sess -d

Notes: 2>&1 is to suppress error output “failed to connect to server: Connection refused”, which occurs when there are no tmux sessions running. -q is used to suppress the normal output of of grep. It won’t affect the result but using it makes the commands less distracting. Regular expression ^sess: is used to make sure it won’t match session name such as “sessionabc” by mistake. Logical operator || is just a shorthand form of if [ ! condititon ]; then … fi.

Example: create a new window title mywin in an existing tmux session mysess, if the window has not existed yet, create the session first if it hasn’t existed yet
#!/bin/bash
sess=mysess
wn=mywin

tmux list-session 2>&1 | grep -q "^$sess" || tmux new-session -s $sess -d
tmux list-window -t $sess 2>&1 | grep -q ": $wn \[" || tmux new-window -t $sess -n $wn

Example: run a script in mysess:mywin in the above example

#!/bin/bash
sess=mysess
wn=mywin

tmux list-session 2>&1 | grep -q "^$sess" || tmux new-session -s $sess -d
tmux list-window -t $sess 2>&1 | grep -q ": $wn \[" || tmux new-window -t $sess -n $wn
tmux send-keys -t $sess:$wn "./dummytask.sh cooking" Enter

How do we know the above script is doing what we intended to do? Check out the next example.

Example: attach tmux session mysess
tmux a -t mysess
Example: run a script in the first window of the newly created tmux session
tmux new-session -s mysess -n mywin "bash dummytask.sh cooking"

This works but there’s a problem, once you exit the program by pressing q or Q, tmux session also terminates. This gets more annoying when a program crashes and you don’t get any debug info, a better handling of the task will be provided in the following example.

Example: run program in a tmux window and exit to bash shell inside the window if the program exits or crashes
#!/bin/bash
sess=mysess
wn=mywin

# duplicate session or window handling code here
# ...
tmux send-keys -t $sess:$wn "./dummytask.sh cooking" Enter
Example: how to check if a tmux session is attached

Sometimes it’s desired to run certain command not in a tmux window, use the following code to detect if attempt is made to run some command inside a tmux window:

if [ "$TERM" = "screen" -a -n "$TMUX" ]; then
    echo "This command should be run when tmux is not attached"
fi
Example: attach a tmux session with a specific window selected
#!/bin/bash
sess=mysess

tmux list-session 2>&1 | grep -q "^$sess" || tmux new-session -s $sess -d


wn=win0
tmux list-window -t $sess 2>&1 | grep -q ": $wn \[" || tmux new-window -t $sess -n $wn
tmux send-keys -t $sess:$wn "./dummytask.sh task 0" Enter

wn=winX
tmux list-window -t $sess 2>&1 | grep -q ": $wn \[" || tmux new-window -t $sess -n $wn
tmux send-keys -t $sess:$wn "./dummytask.sh important mission" Enter

wn=win1
tmux list-window -t $sess 2>&1 | grep -q ": $wn \[" || tmux new-window -t $sess -n $wn
tmux send-keys -t $sess:$wn "./dummytask.sh another thing" Enter


# here's the meat of this script, select window winX before attaching the session
tmux select-window -t $sess:winX && tmux a -t $sess
Advertisements
Categories: Programming, tmux
  1. March 9, 2012 at 11:16 am

    HI,

    Is it possible to make tmux use bash even if my default shell is bash?
    Cheers

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: