<< August 13, 2006 | Home | August 15, 2006 >>

Ten Steps To Higher Cygwin Productivity

I always do these when I get on a new Windows box.

Cygwin is an integral part of my life on Windows boxes. It's the first thing I install when I get on a Windows box. If you take a look at the first screenshot from my new laptop that I posted 9 days ago you will see the Cygwin icon

already present.

In many respects, Cygwin is the GNU operating system based on the cygwin1.dll kernel. As a matter of fact, the cyg part of the Cygwin name originally stands for Cygnus, an Free Software support company that was bought by Red Hat; and gnu is embedded Cygnus. However, many of the applications and services that come with Cygwin is not turned on by default. Some of them even needed a little hand configuration. The following is a list of the first ten things that I always end up doing for every Cygwin installation that I use:

  1. When installing Cygwin, choose Install from Internet instead of the two step Download Without Installing followed by Install from Local Directory. I used to do the two step operations but recognized one day that the only thing I've ever done with the downloaded copies of tar files after the initial installation is to delete them. I also select to install everything because that's the easiest thing to do.
  2. Add C:\cygwin\usr\X11R6\bin\startxwin.bat to my startup menu so that X is running upon reboot. I use multiple xterms running bash as my command shells. They are far easier to use than the Windows XP CMD.EXE shell. Features that I use in the xterm/bash combination include easier copy and past between xterms, command and file name completion, and command history recall using the Emacs-y C-R <cmdline>. The supplied startxwin.bat opens only one xterm. I usually modify it to open four xterms with proper locations and huge scroll buffers big enough for a day's work:
    %RUN% xterm -sl 10240 -sb -geometry 115x29+0+0 -title xterm1 -e /usr/bin/bash -l
    %RUN% xterm -sl 10240 -sb -geometry 115x29+0-102 -title xterm2 -e /usr/bin/bash -l
    %RUN% xterm -sl 10240 -sb -geometry 115x29-12+0 -title xterm3 -e /usr/bin/bash -l
    %RUN% xterm -sl 10240 -sb -geometry 115x29-12-102 -title xterm4 -e /usr/bin/bash -l
  3. Schedule a daily run of the updatedb program. This program updates the filename database that allows my to locate my files very quickly. I could use the Windows scheduler, but cron is easier to manipulate. Cron depends on a mail transport agent, such as ssmtp:
    [weiqi@gao] $ /usr/bin/ssmtp-config
    (Answer questions)
    [weiqi@gao] $ /usr/bin/cron-config
    (Answer questions: yes as a service, no as self, yes ntsec)
    [weiqi@gao] $ crontab -e
    MAILTO=mymail@address.com
    # update the filename database at midnight everyday
    0 0 * * * updatedb --localpaths=c:/
    For ntsec to work, the environment variable CYGWIN must contain the word ntsec. Once the database is updated, I can find files by their names very quickly:
    [weiqi@gao] $ locate jvm.dll
    c:/Program Files/Java/jdk1.5.0_07/jre/bin/client/jvm.dll
    c:/Program Files/Java/jdk1.5.0_07/jre/bin/server/jvm.dll
    c:/Program Files/Java/jre1.5.0_07/bin/client/jvm.dll
    c:/Program Files/JetBrains/IntelliJ IDEA 5.1/jre/bin/client/jvm.dll
  4. Turn on the openssh daemon so that I can ssh into the box from remote locations:
    [weiqi@gao] $ /usr/bin/ssh-host-config
    (Answer questions: no priv separation, yes as service, etc.)
    [weiqi@gao] $ net start sshd
    The CYGWIN sshd service is starting.
    The CYGWIN sshd service was started successfully.
    
    Cygwin also provides a script (/usr/bin/ssh-user-config) that generate the private and public keys for a user. Since I already generated my keys elsewhere, I can just copy my ~/.ssh directory from another machine.
    [Weiqi Gao@gao-2007] $ ssh weiqi@gao-2006
    Enter passphrase for key '/home/Weiqi Gao/.ssh/id_rsa': 
    Last login: Fri Aug 11 20:51:31 2006 from gao-2007.weiqigao.com
    
    [weiqi@gao-2006] $ ssh Weiqi\ Gao@gao-2007
    Enter passphrase for key '/home/weiqi/.ssh/id_rsa': 
    Last login: Fri Aug 11 20:55:35 2006 from gao-2006.weiqigao.com
    Fanfare!!!
    You are successfully logged in to this server!!!
    [Weiqi Gao@gao-2007] $
    I used to turn telnetd and ftpd on too. With sshd working, I don't need those programs any more.
    I still need to learn how to start ssh-agent and put my keys there on reboot so that I don't have to type my passphrase on every ssh connection.
  5. Turn on the PostgreSQL database that is distributed as part of Cygwin. PostgreSQL contains some quite advanced features. As a developer, sometimes it is very handy to have a relational database engine. PostgreSQL relies on a service called cygserver for some IPC support (e.g., shm, etc.):
    [weiqi@gao] $ cygserver-config
    (Answer question: yes as a service)
    [weiqi@gao] $ net start cygserver
    The CYGWIN cygserver service is starting.
    The CYGWIN cygserver service was started successfully.
    
    For the cygserver program to work, the CYGWIN environment variable must contain the word server.
    The command sequence:
    [weiqi@gao] $ /etc/rc.d/init.d/postgresql initdb
    [weiqi@gao] $ /etc/rc.d/init.d/postgresql install
    [weiqi@gao] $ /etc/rc.d/init.d/postgresql start
    ought to be enough to get PostgreSQL installed and started. But it isn't. I've written about this topic before. I still need to change some permissions manually to get things going.
  6. Turn on (uncomment) the aliases that are predefined in the default ~/.bashrc file. These aliases codify some of the command line switches that are commonly used with certain commands and provide an easier way to access them:
    # Aliases
    # #######
    
    # Some example alias instructions
    # If these are enabled they will be used instead of any instructions
    # they may mask.  For example, alias rm='rm -i' will mask the rm
    # application.  To override the alias instruction use a \ before, ie
    # \rm will call the real rm not the alias.
    
    # Interactive operation...
    alias rm='rm -i'
    alias cp='cp -i'
    alias mv='mv -i'
    
    # Default to human readable figures
    alias df='df -h'
    alias du='du -h'
    
    # Misc :) 
    alias less='less -r'                          # raw control characters
    alias whence='type -a'                        # where, of a sort
    alias grep='grep --color'                     # show differences in colour
    
    # Some shortcuts for different directory listings
    alias ls='ls -hF --color=tty'                 # classify files in colour
    alias dir='ls --color=auto --format=vertical'
    alias vdir='ls --color=auto --format=long'
    alias ll='ls -l'                              # long list
    alias la='ls -A'                              # all but . and ..
    alias l='ls -CF'                              #
    The color grep alone is worth the this effort:
    [weiqi@gao] $  grep seakeasy /etc/ssmtp/ssmtp.conf
    mailhub=mail.seakeasy.net
    (I misspelled my mail server address when I was configuring ssmtp, and cron logged an error saying sendmail cannot open mail.seakeasy.net:25.)
  7. Change the default paper size for enscript in /etc/enscript.conf from A4 to Letter. I use enscript to print code listings. It is capable of generating color syntax highlighted PostScript code listings for Java, JavaScript, C++, Perl, Python, Scheme, AWK, and many many more languages. I use the following ENSCRIPT environment variable
    export ENSCRIPT="-G2rE --color -C --word-wrap"
    to tell enscript to format my code listings with a fancy header, two columns in landscape mode, detect the language, use color syntax highlighting, print line numbers, and wrap long lines at word boundaries. Here's an example output.
  8. Turn on the Apache Web Server. Both Apache HTTP Server 1.x and 2.x are included in the Cygwin setup. To turn on Apache HTTPD Server 2, simply do:
    [weiqi@gao] $ cygrunsrv -I httpd2 -d "CYGWIN httpd2" -p /usr/sbin/httpd2 \
              -a "-DNO_DETACH" -y cygserver -e "CYGWIN=server" -s TERM -o
    [weiqi@gao $ net start httpd2
    The CYGWIN httpd2 service is starting.
    The CYGWIN httpd2 service was started successfully.
    By opening up the http port on the Windows Firewall, I can easily share files to coworkers by simply copying them to the web document directory. I can then email them a URL. It's also a good way of sharing Javadocs and Doxygen docs.
  9. Cygwin is much more than simply a pile of exploded jar files. A couple of Cygwin specific commands are particularly useful.
    The first one is the cygcheck command. For the longest time, I thought it is just a command that somehow checks my Cygwin installation. However, reading its man pages convinced me that it is more than that. It is actually a package management system much like rpm or dpkg. For example, earlier today, I wondered about the lpr command from Cygwin. By doing a
    [weiqi@gao] $ cygcheck -f /usr/bin/lpr.exe
    cygutils-1.3.0-1
    I found out that it belongs to the cygutils package. A follow on command of
    [weiqi@gao] $ cygcheck -l cygutils
    /usr/bin/ascii.exe
    /usr/bin/banner.exe
    /usr/bin/conv.exe
    /usr/bin/cygstart.exe
    /usr/bin/d2u.exe
    /usr/bin/dos2unix.exe
    /usr/bin/dump.exe
    /usr/bin/getclip.exe
    /usr/bin/ipck
    /usr/bin/lpr.exe
    /usr/bin/mkshortcut.exe
    /usr/bin/msgtool.exe
    /usr/bin/putclip.exe
    /usr/bin/readshortcut.exe
    /usr/bin/realpath.exe
    /usr/bin/semstat.exe
    /usr/bin/semtool.exe
    /usr/bin/shmtool.exe
    /usr/bin/u2d.exe
    /usr/bin/unix2dos.exe
    ...
    pointed me to the other commands and documentations of the package.
    The second useful command is actually part of this cygutils package. The cygstart command mimics the Windows native start command in that you can say
    [weiqi@gao] $ cygstart project.sln
    to start a Microsoft Visual Studio .NET 2003 solution file. I aliased this command to start so that when other developers come to my Cygwin xterm and do a start project.sln it would still work.
  10. Take advantage of bash's initialization scripting infrastructure for setting up environment variables for user installed software packages. Just like on Linux systems, when a Cygwin bash login shell starts, it executes a sequence of initialization files, including /etc/profile and ~/.bash_profile. The script /etc/profile contains a mechanism for sourcing all *.sh files in the /etc/profile.d directory. So you can cause a script to be sourced on start up by simply putting it there.
    Here's my /etc/profile.d/maven.sh (I'm experimenting with Maven's facility to generate IntelliJ and Eclipse project files from pom.xml files)
    # Maven 2.0.4 initialization script
    #
    APP_HOME=/opt/maven-2.0.4
    APP_PATH=$APP_HOME/bin
    
    if ! echo $PATH | grep -q $APP_PATH
    then
      if [ -z "$PATH" ]
      then
        PATH=$APP_PATH
      else
        PATH="$PATH:$APP_PATH"
      fi
    fi
    
    export PATH
    unset APP_HOME APP_PATH
    
    It simply adds /opt/maven-2.0.4/bin to the PATH environment variable. At first it might look like an overkill. However most of the file is boilerplate. When I installed Maven, I simply copied my /etc/profile.d/jdk.sh into maven.sh and changed the APP_HOME=... line. I know I can extract the bulk of the script into an addpath function, I just haven't done it yet.
    Java CLASSPATH's can be handled similarly. However, since Cygwin does not convert CLASSPATH into Unix format, when I add to the CLASSPATH I need to do some conversions myself. First convert CLASSPATH into Unix format. Then add my portion (in Unix format) into the converted CLASSPATH. Finally convert the CLASSPATH back to Windows format. You can read the $ANT_HOME/bin/ant file to see how this is done.

I wrote this entry one piece at a time as I'm configuring my new laptop. And I'm doing this as much for myself as for the readers of this blog. The next time I install Cygwin on a new computer, I can just print this article out and follow the steps.

I started using Cygwin almost a decade ago, starting from Beta 16. I still remember a huge (10MB) hidden file that Cygwin created on my Windows 95 hard drive that I simply cannot get rid of. Cygwin has come a long way since then. I'm sure there are other parts of Cygwin that is really handy but I just haven't had the chance to explore yet.

Tags :