DVTM – dynamic virtual terminal manager
Monday, February 11th, 2008
I do a lot of remote UNIX administration on various servers and even some desktop machines. This usually means that I’m doing a lot of SSHing into machines, often opening multiple sessions to the same machine at the same time. It quickly becomes tedious to keep having to type ‘ssh fboender@some.machine.com‘ four times in order to get four sessions.
Of course there is Screen, but Screen’s split screen abilities are very limited and don’t really work for me. While scanning Freshmeat.net, I found a tool called DVTM: dynamic virtual terminal manager.
DVTM is a kind of window manager for the console (or xterm) which allows you to quite easily split your terminal into multiple split screens.
DVTM has some limitations though:
- Configuration is done using C code. (Though you’ll probably never need to change anything; the defaults are quite sane)
- It doesn’t seem to support ANSI colouring. I use a red background at my prompt when I’m root, which I now have to miss.
- It also doesn’t seem to support line-drawing. This probably has something to do with the terminal type.
- DVTM has no internal support for detaching and reattaching to running DVTM instances like Screen can. (But see the Tips and tricks section on the homepage).
- There are a couple of small bugs, one of which is a problem with repeating keys when switching between split windows with the mouse.
But make no mistake: despite these shortcomings, DVTM is an absolutely fantastic tool. Some of the neat stuff it supports is:
- Mouse support for switching between split windows / maximizing and unmaximizing, etc.
- Maximize/unmaximize the currently active window (Default: Ctrl-g m / Ctrl-g g)
- Various window layouts (you can probably add your own by hacking the source code)
- Almost no dependencies except for ncurses.
The only thing I’d really like to see changed about DVTM are custom run-time splitting (for instance, Ctrl-g-MINUS to split the current window horizontally and Ctrl-g-PIPE to split the window vertically) and detaching/reattaching.
All in all, DVTM is an awesome tool. Go download it if you do a lot of remote administration.
Update: There also appear to be two bugs:
- On the latest Ubuntu: Sometimes when exiting DVTM, it will hang for a while, and the cursor will blink like mad. An strace shows that IO Errors are occuring on file descriptor 3. I’ve filed a bug report with the author. This bug doesn’t appear on Debian stable.
- When using DVTM in combination with dtach, reattaching doesn’t redraw the screen. This appears to be a problem with DVTM, but it would probably be easier to solve in dtach (which could just signal a screen resize event without actually resizing the screen). This is also the workaround for this bug: just resize the window. I’ll see if I can file a bug report with either DVTM’s author or dtach’s author.
Update II: Here’s a little patch/workaround for the first bug (exiting DVTM hangs for a while):
--- dvtm.c 2008-02-06 17:30:25.000000000 +0100 +++ ../dvtm-0.4/dvtm.c 2008-02-11 23:33:45.000000000 +0100 @@ -896,6 +896,7 @@ Client *c; int r, nfds = 0; fd_set rd; + struct timeval tv; if(need_screen_resize) resize_screen(); @@ -996,6 +997,13 @@ wnoutrefresh(sel->window); } doupdate(); + + // One microsecond delay so this loop doesn't hang context-switching + // when the last child dies and the SIGCHLD signal is prevented from + // being caught on time. + tv.tv_sec = 0; + tv.tv_usec = 1; + select(0, NULL, NULL, NULL, &tv); } cleanup();
Save to ~/patch.diff and in the dvtm-0.4 directory run:
~/dvtm-0.4$ patch -p0 < ~/patch.diff
Update III:
I was incorrect in stating that dvtm doesn't support ANSI coloring. It's just the bash prompt which doesn't work. Perhaps because there is a Xterm-styled window title ANSI sequence in there. Will update when I know more.
Update IV:
Marginally better patch:
diff -Naur ./dvtm.c ../dvtm-0.4/dvtm.c --- ./dvtm.c 2008-02-06 17:30:25.000000000 +0100 +++ ../dvtm-0.4/dvtm.c 2008-02-12 22:08:54.000000000 +0100 @@ -982,7 +982,10 @@ for(c = clients; c; c = c->next){ if(FD_ISSET(c->pty, &rd)){ - madtty_process(c->term); + if (madtty_process(c->term) < 0 && errno == EIO) { + /* client probably terminated */ + client_killed = c; + } if(c != sel){ draw_content(c); if(!isarrange(fullscreen))