Random notes from mg

a blog by Marius Gedminas

Marius is a Python hacker. He works for Programmers of Vilnius, a small Python/Zope 3 startup. He has a personal home page at http://gedmin.as. His email is marius@gedmin.as. He does not like spam, but is not afraid of it.

Fri, 10 Mar 2006

Bash prompts: showing the command in the window title

I've been using Linux for almost 10 years now, so I'm used to the command line. Most of the windows in my GNOME desktop are GNOME Terminals. And when you have many of them, you'd like to distinguish them somehow in the window list or window selector applets.

My .bashrc specifies a $PROMPT_COMMAND that sets the username, hostname and the current working directory in the title bar. I can therefore distinguish root terminals and remote terminals (ssh rules), and terminals where I work on different projects in different directories. Until recently I couldn't, however, distinguish the terminal which was running Zope 3 from a terminal which was running functional tests from a terminal which was running an svn update.

For a long time I wanted to see the currently executing command in a terminal title. I always thought this was impossible with bash. David Pashley proved me wrong. I had to change his recipe a little bit, because it interferes with $PROMPT_COMMAND in a nasty way. Here's my .bashrc now:

# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
    PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"'

    # Show the currently running command in the terminal title:
    # http://www.davidpashley.com/articles/xterm-titles-with-bash.html
    show_command_in_title_bar()
    {
        case "$BASH_COMMAND" in
            *\033]0*)
                # The command is trying to set the title bar as well;
                # this is most likely the execution of $PROMPT_COMMAND.
                # In any case nested escapes confuse the terminal, so don't
                # output them.
                ;;
            *)
                echo -ne "\033]0;${USER}@${HOSTNAME}: ${BASH_COMMAND}\007"
                ;;
        esac
    }
    trap show_command_in_title_bar DEBUG
    ;;
*)
    ;;
esac
posted at 10:02 | tags: | permanent link to this entry | 4 comments

Wed, 08 Mar 2006

Dual-Headed Productivity

my workplace

There's an LCD monitor standing on the desk next to my laptop at work. I use MergedFB to get a combined 1024x786+1280x1024 desktop. (Here's my /etc/X11/xorg.conf if anyone with a Radeon card is interested.)

GNOME doesn't fully understand this setup yet (bug #147808). It thinks I have a single large 2304x1024 desktop, and it sets the wallpaper accordingly. I can tile or stretch an image, but I cannot set separate images for each monitor. And tiling doesn't work well with different monitor resolutions.

What I needed was a tool to take two images, scale them appropriately and paste them together into one large 2304x1024 image. Easy! I did some browsing of the Python Imaging Library online documentation and 45 minutes later I had dualpaper.py, a nice command-line script with robust option parsing.

Encouraged by easy success I took on the next challenge: writing a GUI app so that I could drag and drop a couple of images, hit a button, and get a newly constructed wallpaper. This was a bit harder. I used PyGtk and Glade. I spent some frustrating time trying to locate PyGtk examples (to see how drag&drop works) until I finally located them in /usr/share/doc/python2.4-gtk2/examples/demos/. I spent even more time Googling about Xinerama so that I could automatically determine the size of each monitor, until I discovered gtk.gdk.Screen.get_monitor_geometry. The rest was straightforward, and I had a fully functional prototype in less than 2 hours.

Dual-Head Wallpaper Maker

That's why I love Python: it enables me to achieve results very quickly. (By the way, how do I know this excercise took 2 hours and 34 minutes? GTimeLog!).

Update: the code now has a webpage.

posted at 02:23 | tags: | permanent link to this entry | 0 comments

Wed, 01 Mar 2006

Sysadmin's diary

Many texts on Linux/Unix system administration advise you to have a diary and write down everything you do. I have finally realized the wisdom of this advice.

I use a simple shell script /usr/local/sbin/new-changelog-entry. This script adds the current date and time to a file /root/Changelog and opens it in a text editor. I usually have two terminals (or two tabs in GNOME Terminal): one has a root shell where I do things, the other has vi with /root/Changelog. I write down everything I change, and usually copy the exact commands I executed. This lets me redo the same thing very easily after OS upgrades, or on a different server.

Here are a couple of sample entries from my laptop:

2005-09-23 11:44 +0300: mg
  #
  # Overcoming the 2 GB limit with Samba: http://brianpuccio.net/node/664
  #
  vi /etc/auto.misc
    added 'lfs' to the options of all smbfs filesystems
  /etc/init.d/autofs reload

2006-02-17 10:48 +0200: mg
  #
  # Installing Firefox 1.5 (from Dapper) on Ubuntu Breezy
  #
  # (I do not want to upgrade half of my system, so I'll compile the Dapper
  # debs from source)
  sudo -u mg -s
    cd /home/mg/src/apt-sources/
    apt-get source firefox
    cd firefox-1.5.dfsg+1.5.0.1/
    dpkg-buildpackage -uc -us -b -rfakeroot
    # ...45 minutes later...
  cd /home/mg/src/apt-sources/
  dpkg -i firefox_1.5.dfsg+1.5.0.1-1ubuntu3_i386.deb \
          firefox-dev_1.5.dfsg+1.5.0.1-1ubuntu3_i386.deb \
          firefox-dom-inspector_1.5.dfsg+1.5.0.1-1ubuntu3_i386.deb \
          firefox-gnome-support_1.5.dfsg+1.5.0.1-1ubuntu3_i386.deb \
          libnspr4_1.firefox1.5.dfsg+1.5.0.1-1ubuntu3_i386.deb \
          libnspr-dev_1.firefox1.5.dfsg+1.5.0.1-1ubuntu3_i386.deb \
          libnss3_1.firefox1.5.dfsg+1.5.0.1-1ubuntu3_i386.deb \
          libnss-dev_1.firefox1.5.dfsg+1.5.0.1-1ubuntu3_i386.deb

Update: here's a similar idea that goes further (not just changelogs, but also description pages for each machine): My electronic sysadmin notebook for an entire fleet by Rachel Kroll.

posted at 23:10 | tags: | permanent link to this entry | 0 comments