Spawn a Styled xterm into Home and Disown It

First, I set up the styling (no scrollbar, font, font size, background, and foreground colors):

xterm +sb -fa monaco -fs 10 -bg black -fg white

Next, I redirected the output and backgrounded the process:

xterm +sb -fa monaco -fs 10 -bg black -fg white > /dev/null 2>&1 &

This worked well for quite a while, but when I spawn a shell in an arbitrary directory, I wanted my shell to start in home so I added:

eval $( cd ; xterm +sb -fa monaco -fs 10 -bg black -fg white > /dev/null 2>&1 & )

Finally, I wanted to fully disown the new xterm from the shell I spawned it from. Therefore, my .bash_aliases file now has:

alias term='eval $( cd ; xterm +sb -fa monaco -fs 10 -bg black -fg white > /dev/null 2>&1 & disown %1 )'

Now I can cleanly spawn a new terminal that sends no output to the existing shell.

Run a Shell Command in a Makefile

I had a directory of BMP image files that I wanted to convert to EPS (Encapsulated PostScript). Since I was planning on adding files to the directory, I did not want to hard code the names of the files into the makefile that would do the conversion. Therefore, the trick was to run a shell command inside of the makefile. The first line lists all of the BMP files and assigns it to “BMP_FILES”. The next line replaces the “bmp” extension with “eps”. The complete makefile is below.

BMP_FILES = $(shell ls *.bmp)
EPS_FILES = ${BMP_FILES:%.bmp=%.eps}

all: ${EPS_FILES}

%.eps : %.bmp
	convert $*.bmp $*.eps

All that is left is to type “make” in the directory, and all of the BMP files will be converted to EPS.

Bad Bash Sourcing

A while back I switched such that my .bash_profile sources my .bashrc instead of the reverse. Based on a few sources, this seems to be the preferred approach. Today I decided to push those files to a few servers that haven’t been updated lately. I transferred my .bash_profile and then my .bashrc:

zac@dakara:~$ scp ~/.environment/bash/bash_profile lansky:~/.bash_profile
bash_profile                                  100%  120     0.1KB/s   00:00    
zac@dakara:~$ scp ~/.environment/bash/bashrc lansky:~/.bashrc
lost connection

What happened? My .bash_profile sources my .bashrc, but since I hadn’t yet replaced the .bashrc, it still sources my .bash_profile. That means infinite loop and that I am an idiot. SSH, rsync, and scp are all broken. There is no way to remove or replace either of those files without another account. I guess it’s time to open a support ticket at DreamHost.

The moral of the story is to always be careful how you source those files. I usually try to keep an SSH session open on the remote machine when I modify those files in case I break login, but this time I didn’t. A few searches didn’t reveal any solutions. I’d love to know if someone has a way of resolving this without access to another account on the remote machine.

Advanced Bash Completion

Ubuntu has a lot of advanced bash completion features that simplify using the shell. For example, when using the ssh command, I can tab complete server names based on my host file and my ssh config file. It turns out that most of this is accomplished with one bash_completion script. This page has a lot of useful information about the Bash shell and also the very useful script. I’ve found that when I use Fedora in the Xinu lab, I am left typing a lot of this stuff myself. Since I use the same bashrc file on both Dakara and my lab machine (Kastria), I didn’t want to always resource the file so I added this to my bashrc:

# Source global definitions
[ -f /etc/bashrc ]      && source /etc/bashrc
[ -f /etc/bash.bashrc ] && source /etc/bash.bashrc
# enable programmable completion features
if [ -z "$BASH_COMPLETION" \
    -a -r ~/.configuration/bash/bash_completion.caliban ]; then
    BASH_COMPLETION=~/.configuration/bash/bash_completion.caliban
    source $BASH_COMPLETION
fi

First, I source the global definitions, Ubuntu uses /etc/bashrc, and Fedora uses /etc/bash.bashrc. After that, if the bash_completion script was already sourced, $BASH_COMPLETION will be set. I check to see if it is zero length (-z) and then source my own copy of it if it is. Now I have advanced bash completion on both Ubuntu and Fedora.

Install Flash on Mac OS X from the command line

My mother needed the latest version of Flash to view a web page. I decided this was a good opportunity to install the package from the command line over secure shell. She has a PowerMac G4 running Mac OS X 10.4. It turns out that the update didn’t work, but I relearned a bit about some useful command line tools for Mac OS X. I always start in the temp directory. Then I downloaded the installer and unzipped it. That’s all pretty straightforward.

cd /tmp/
curl -O http://fpdownload.macromedia.com/get/flashplayer/current/install_flash_player_osx_ub.dmg.zip
unzip install_flash_player_osx_ub.dmg.zip

Next, I used “hdiutil” to mount the disk image and then changed to that directory.

hdiutil attach Install\ Flash\ Player\ 10\ UB.dmg
cd /Volumes/Install\ Flash\ Player\ 10\ UB/

Then I used “installer” to install the package specifying the package with “-pkg Adobe\ Flash\ Player.pkg” and the target volume with “-target /”.

installer -verbose -pkg Adobe\ Flash\ Player.pkg -target /

It will run through the installation and output some information. After that, I changed back to the temp directory. I initially tried using “umount” to unmount the disk image, but that is a bad idea because it doesn’t fully unmount the image. The better approach is to use the “hdiutil” again. I find the volume to unmount by using the “df” command. Once it is unmounted, I deleted the zip file and the disk image.

cd /tmp/
hdiutil detach $(df | grep Flash | awk '{print $1}')
rm install_flash_player_osx_ub.dmg.zip
rm Install\ Flash\ Player\ 10\ UB.dmg

Most applications for Mac OS X come in disk images, and many of those have package installers. This is a quick way to install software on a remote Macintosh or a way to automate installations with scripts.

Your own personal man directory

Recently, I wanted to install a program in my home bin directory, and it had a man page to go with it. I started looking for a way to create my own personal man directory. According to the manual page for man, “man uses a sophisticated method of finding manual page files.” Indeed it does. It turns out that all I had to do was create a man directory inside of my home directory and man would know it was there:

zac@dakara:~$ manpath 
/usr/local/man:/usr/local/share/man:/usr/share/man
zac@dakara:~$ mkdir man
zac@dakara:~$ manpath 
/home/zac/man:/usr/local/man:/usr/local/share/man:/usr/share/man

Then to install the man page, I simply had to create the appropriate directory structure and copy the man page in:

zac@dakara:~$ mkdir -p man/en/man1/