Archive

Archive for the ‘tmux’ Category

tmux techniques by example

November 14, 2011 2 comments

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

Attach targeted window using tmux

August 5, 2011 Leave a comment

In tmux sometimes we might need to attach a session with the specific window selected so that we can start working without additional switching window steps. I just found one of the ways to accomplish this is:

tmux select-window -t sess:win && tmux attach -t sess

Credit goes to http://tofu.org/drupal/node/183 [ lines 78 & 79 ]

Categories: Tip, tmux

How to get out from tmux session inside a tmux window

June 8, 2011 7 comments

Here’s how I got stuck:
1) Remote access to a linux serverA
2) Launch tmux, Ctrl-b c to create a new window
3) From the new window, remote access to serverB, then run tmux att under shell to attach an existing tmux session (on serverB)
4) Now if I use the shortcut key Ctrl-b d, I can only detach from the session on serverA, because the tmux session on server B also uses Ctrl-b as the prefix

The fix:
a) Press Ctrl-b n until the window containing the ssh session to server B becomes the current window
b) Press Ctrl-b :
c) Enter tmux command set -g prefix C-a
d) Press Ctrl-b d, tmux session on serverB is now detached, type exit to close the new window created in step 2, this step is optional though as the “nested” tmux session is detached from the ssh shell
e) Press Ctrl-a :
f) Enter tmux command set -g prefix C-b

Step c changes prefix to Ctrl-a so it won’t conflict with the tmux shortcut prefix from serverB. Step f changes the prefix back to Ctrl-b for serverA.

Categories: howto, Tip, tmux