Technology

Rethought zshrc

I’ve been using zsh for a while as my preferred shell. I have a hacked-together zshrc file, and yet really wanted to use it across multiple systems. Some of those systems are running Mac OS X, others Solaris, and still others Linux. Executables are in a different locations and even have different switches across this range of systems, so my cobbled zshrc was not helping me.

As I was about to fall asleep last night, it finally hit me that fixing my zshrc would be a good thing to do. I jotted down some notes about an idea to reorganize it, and did something about it today.

Of course, since I’ve checked my zshrc and other dotfiles into a Mercurial repository, I could experiment without fear.

I created three top-level functions, with one “case” statement in each. Case statements may be evil in some fashion, but they are one of the things I like about shell scripting. These statements do allow the script to make choices based on the host, operating system, or shell that it was running in. (Yeah, it’s a zshrc, but I sometimes do stupid things — like sourcing it in bash on the one Linux system that won’t let me switch to zsh. Site5, I’m looking at you.)

I separated all the important sections of my zshrc into their own individual function calls. Each of those function calls was placed into one of the applicable case statements.

The case statement functions figure out the conditions the zshrc is running in, and then run the other functions to set up my environment.

The changes tested well from first try across the various platforms and hosts I log in to. I did have a minor problem with the `hostname` command, because Solaris doesn’t have a “-s” flag for it. Eventually, I solved that — and the odd “uname: error in setting name: Not owner” error I got, even though I wasn’t directly running `uname` there — by replacing `hostname` with `uname`.

Thankfully, it works for me, and it should be a little easier to manage changes in the future.

Compiling a five-way Universal Binary of Rsync 3 with LLVM-GCC on Leopard

The Xcode 3.1 Developer Tools install both the standard GNU compiler, gcc, and the LLVM compiler, llvm-gcc. I thought I’d try my hand at compiling something with LLVM, so naturally I decided to update my instructions for compiling Rsync 3 as a Universal Binary for Leopard. Let’s try Rsync 3.0.3!

The following set of instructions, of course, requires that you have already installed the Xcode 3.1, available as a download from Apple. To choose LLVM as your C compiler temporarily for this compile, specify the CC=“/Developer/usr/bin/llvm-gcc” variable (as explained in the LLVM FAQ).

$ cd /tmp
$ curl -O curl -O http://rsync.samba.org/ftp/rsync/rsync-3.0.3.tar.gz
$ tar -xzvf rsync-3.0.3.tar.gz
$ rm rsync-3.0.3.tar.gz
$ curl -O http://rsync.samba.org/ftp/rsync/rsync-patches-3.0.3.tar.gz
$ tar -xzvf rsync-patches-3.0.3.tar.gz
$ rm rsync-patches-3.0.3.tar.gz
$ cd rsync-3.0.3
$ patch -p1 <patches/fileflags.diff
$ patch -p1 <patches/crtimes.diff
$ ./prepare-source
$ env CFLAGS="-O -g -isysroot /Developer/SDKs/MacOSX10.5.sdk -arch i386 \
-arch ppc7400 -arch ppc970 -arch ppc64 -arch x86_64" LDFLAGS="-arch i386 \
-arch ppc7400 -arch ppc970 -arch ppc64 -arch x86_64" \
CC="/Developer/usr/bin/llvm-gcc" \
./configure --prefix=/usr/local --disable-dependency-tracking

$ make
$ ./rsync --version
rsync version 3.0.3 protocol version 30
Copyright (C) 1996-2008 by Andrew Tridgell, Wayne Davison, and others.
Web site: http://rsync.samba.org/
Capabilities:
64-bit files, 32-bit inums, 64-bit timestamps, 64-bit long ints,
socketpairs, hardlinks, symlinks, IPv6, batchfiles, inplace,
append, ACLs, xattrs, no iconv, symtimes, file-flags
rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you
are welcome to redistribute it under certain conditions. See the GNU
General Public Licence for details.
$ file ./rsync
./rsync: Mach-O universal binary with 5 architectures
./rsync (for architecture i386): Mach-O executable i386
./rsync (for architecture ppc7400): Mach-O executable ppc
./rsync (for architecture ppc970): Mach-O executable ppc
./rsync (for architecture ppc64): Mach-O 64-bit executable ppc64
./rsync (for architecture x86_64): Mach-O 64-bit executable x86_64
$ lipo -info ./rsync
Architectures in the fat file: ./rsync are: i386 ppc7400 ppc970 ppc64 x86_64
$ sudo make install

Warning: I have not tested Rsync 3 compiled with LLVM to ensure that it operates at all or is compatible with Rsync compiled by GCC. I haven’t compared the compilation speed against GCC’s performance, determined whether the files are larger/smaller, or have produced a more optimized binary. You use the software compiled with these instructions at your own risk.

Most of the original instructions were helpfully documented by Mike Bombich. My contributions are simply:

  • Universal Binary support: four- or five-way, depending on whether you want to use “-arch i386 -arch ppc7400 -arch ppc970 -arch ppc64 -arch x86_64” (which gives specific optimized binaries for PowerPC G4 and G5 systems in 32-bit mode) or “-arch i386 -arch ppc -arch ppc64 -arch x86_64” (for more general 32-bit PowerPC support, as I did in my previous article).
  • LLVM compilation: use of the llvm-gcc front end, which hopefully produces a working Rsync 3.

Finding and viewing the Test Print document in Mac OS X Leopard

When you have the print queue window open for a printer in Mac OS X Leopard, the Printer menu > Print Test Page command is active. That command sends the CUPS test page to the selected print queue.

The test page file itself is a PostScript document located at this path:

/usr/share/cups/data/testprint.ps

Since Leopard — like Mac OS X versions since Panther, has a built-in PostScript interpreter — you can open up this PostScript document and have it rendered as a PDF. By default, it will be sent to the Preview application.

It’s helpful to be able to view this document on-screen, so you can see what it is supposed to look like, in case your printer is not working as intended. You can compare the on-screen results with the printed output to verify how well your printer is working.

Mac OS X Service to create the man page URL for a command

Mac OS X has a type of URL specifically for opening UNIX man pages. For me, using one of these URLs opens a new Terminal window to display the man page. Just put the name of the man page after the “x-man-page://” URL scheme to create one of these URLs.

For example, a link to the rsync man page would look like “x-man-page://rsync” when written out.

This is a handy way to refer to UNIX man pages with other Mac OS X users in e-mail correspondence, on mailing lists, or on the Web. Because of that, I wanted a quicker way to create these man page URLs. I wrote the Mac OS X Service named “Man Page URL for Command” to satisfy that desire. The “Man Page URL for Command” Service is provided “as-is” with no warranty.

The Service was wrapped up with ThisService by Peter Hosey, as with my earlier Mac OS X Service to shorten a URL with Bit.ly.

To install the Service:

  1. Unzip the downloaded file.
  2. Drag the unzipped Service to /Library/Services (for all users) or ~/Library/Services (for just the current user).

To use it:

  1. Select a single word from some text you can highlight in an application. The word should ideally correspond to the name of a general UNIX command (“ls”), a Mac OS X-specific command (“dsmemberutil”), or another term the matches a man page (“sshd_config”). The Service is specifically coded to work only when you select a single word; if you select a text string with any white space in it, the Service will just return your original text. The Service also checks to ensure that the selected word corresponds to either a command in the $PATH or an existing man page, so it will not generate a “x-man-page://” for just any word.
  2. Choose “Man Page URL for Command” from the Services submenu of the application menu. As long as you have selected only a single word that matches a command or existing man page, the selection will be replaced with the “x-man-page://” URL.

Thanks to Nigel for the inspiration.

AttachmentSize
ManPageUrlForCommand.zip34.45 KB

So long and thanks for the 125,099 miles

Yesterday, I traded in “Fighterjet.”

I feel pretty raw about signing away the title for my 1998 Subaru Legacy GT 2.5 Limited. (Frankly, I’ll never remember the correct order “GT,” “2.5,” and “Limited” are supposed to go in, even after 10 years — 3273 days, to be exact — of car ownership.) Looking back, I took delivery on July 1, 1998.

What do you say about a car you owned for 122 months? A vehicle that was there to transport you through the highs and lows of life?

Well, the brochure for our new car says, “Few things connect to your life at more points than your car.” Amen. I’ll take a stab at a few notes in haphazard arrangement, below.

This will all seem melodramatic, and it is. There are, I’m sure, people who don’t get attached to their cars. My wife and I are not those people. However, I am beginning to realize that you can only really get attached to one car, and thereafter you realize you simply can’t do that again. This is my struggle this morning, and my usual tendencies to hang on are amplified by how long I had that Subaru.

Fighterjet was the first car I ever picked out and bought myself. The two cars before it dropped into my lap, by the generosity of my family, and being young, I did my level best to destroy them quickly. The Subaru had 40-some miles on it when I bought it, partly because I drove it a few times and partly because the test drive area around the dealership was so large.

Every girlfriend I had in my adult life rode in Fighterjet. One of them helped me choose it. The car outlasted all but one of them.

My wife and our first son rode in Fighterjet. In fact, it was the car that Aaron and I had to rescue from the snowy parking lot at work — its door had been jammed open by ice so the alarm was sounding — so that I could collect the bags we’d left at home and return to the hospital with them. The baby was born a day later, and perhaps we’ll be more prepared in the future.

Fighterjet didn’t have LATCH anchors. Oops.

When I bought Fighterjet, I didn’t have any music in MP3 format. Having an iPod connection was unheard of, because the iPod wouldn’t ship for years yet. But it had a CD player and a tape player, not to mention weather band radio. (Weather band radio is really dull.)

Luckily, I had obtained my first digital camera nine months before Fighterjet, so I was able to document the car pretty well.

The month I brought Fighterjet home, I went to Macworld Expo in New York City. It was the first of five such expos in New York (and that was a particularly whirlwind trip), but it was even more memorable for a big product introduction: the original bondi blue iMac. Fighterjet, meanwhile, was “Rio red.”

Hearing about the color of my car, Kristi laughed and said, “Oh, it’s pull-me-over red!” I got exactly one ticket with Fighterjet.

The Sabres had only been to the Stanley Cup Finals once in their history when I started driving Fighterjet. Now, they’ve been there twice. And had a few conference finals appearances, too. (Did Aaron and I drive Fighterjet to that playoff game with Philly? The one that created the wall of sound in the atrium of HSBC Arena? Correction: Aaron says it was this game against Ottawa.)

I drove to a lot of Ultimate games in Fighterjet. Cleaning it out, I had a regulation Frisbee in the trunk. Along with a wiffle bat and some wiffle balls — you never know when an impromptu game would break out.

I spent one long day in Fighterjet, stuck on the New York State Thruway (I-90) for about 15 hours, one winter. There was a big snowstorm. Some of you lived through it with me, and others have probably heard me talk about it, so I don’t think I need to say more. At least that time, I was prepared.

That incident taught me that if you can’t tell your car from other snow-covered cars in the vicinity, you should probably stay home.

Fighterjet drove through a lot of snow, and barely broke a sweat over it. There were a few close calls, though. Once, I hydroplaned through the turn from 96 onto 332 — no wheels gripped, they only slipped. There was one Christmas morning, driving to Cuba, where we spun 180 degrees together; thank goodness the next car was so far behind us. Another morning, going to work and sliding slowly, sideways, into and kissing a (thankfully) snow-packed guardrail.

I didn’t have a cell phone when I bought Fighterjet.

Baxter was in Fighterjet when I hit my second deer with the car, and, as a dog, he was pretty freaked out by the sudden ordeal. I really thought that was the end of the line, but the insurance didn’t total the car. I haven’t taken Baxter with me to get take out since, as I recall.

The car got its name from the view I got sitting in the driver’s seat, looking back through my regular and oddball lane-changer mirrors. It reminded me of the rearview cameras you see in fighter jet films on TV, looking back on the tail of the plane. Dumb, yes, but I couldn’t think of a better name.

I can’t remember how many sets of tires I put on the thing. The first one involved a lot of anxiety while reading reviews on the Tire Rack Web site. The Dunlop Sport SP2s, later, were utter flops.

Fighterjet helped me move between apartments and houses. Thrice. And, I think it helped move Lloyd’s family once, and maybe others. I forget.

I drove it to Pittsburgh and the Adirondacks and other places, but I also think of destinations I never went.

After giving up this car, I wonder how many cars I have left in me. How many more will I own? My sense of mortality is briefly heightened.

I miss Fighterjet, but it was time to move on. I feel like I’ve abandoned a friend — but that’s silly. Hopefully that feeling will fade, because, after all … it was just a car.

Start Directory Service debug logging automatically after the next restart on Mac OS X

There can be times when you need to troubleshoot Directory Services in Mac OS X during system starts up. Directory Services apparently sits above and below the kernel — depending on what each of those components needs to do — so having debugging capability early on in the boot process can help you hone in on problems.

To enable debug logging at startup, run the following at the command line:

$ touch /Library/Preferences/DirectoryService/.DSLogDebugAtStart

… and then, on the next restart, debug logging will be enabled. This is equivalent to running:

$ sudo killall -USR1 DirectoryService

… but the advantage is is that debug logging begins at startup, rather than whenever you can log in and start it manually.

Remove the file from the path above when you want to disable the logging for the subsequent restart. As a file whose name starts with a dot, you won’t see it listed by default in the Finder. (The Finder hides dot files by default.)

$ rm /Library/Preferences/DirectoryService/.DSLogDebugAtStart

Mac OS X Service to shorten a URL with Bit.ly

Since the Bit.ly URL-shortening service is all the rage lately, and I hadn’t seen anyone create a Mac OS X Service for it yet, I decided to try my hand at it.

Here’s the result. The core is a relatively simple Python script and requires Mac OS X 10.5 (or Python 2.5 if you have an earlier version of Mac OS X). The Service was wrapped up with ThisService by Peter Hosey. It’s my first attempt at creating a Mac OS X Service — with or without ThisService — and I hope it works for you. However, it is provided “as-is” with no warranty.

That said, if you have comments or suggestions, please feel free to contact me.

Also, I’m not counting this as an endorsement of Bit.ly; I just looked at info on their site and thought I could probably script it and, as you can see, I did.

To install the Service:

  1. Unzip the downloaded file.
  2. Drag the unzipped Service to /Library/Services (for all users) or ~/Library/Services (for just the current user).

To use it:

  1. Select the full text of an “http” or “https” URL that you’d like to shorten. (Don’t just select a site’s domain name. The Service is specifically coded to work on full URLs starting with “http” or “https.” So, “www.jaharmi.com” will not work but “http://www.jaharmi.com” will.)
  2. Choose “Shorten URL with Bit.ly” from the Services submenu of the application menu. The selected URL will be replaced with the text of the shortened URL from Bit.ly. If it is not, the original URL will remain.

Of special note, however, is that if you shorten URLs with Bit.ly this way rather than through your browser, you probably won’t see them show up in your history (the most recent 15 URLs you’ve shortened). The script just shortens URLs for you and does so outside of your browser, so whatever cookies or other tracking Bit.ly is doing to generate your history, it doesn’t appear to carry over when using this simple little Service.

AttachmentSize
ShortenUrlWithBitly.zip34.17 KB

LaunchBar Search Template for the MacEnterprise mailing list

If you want to search the mailing list archives for the MacEnterprise.org list with LaunchBar’s Search Templates feature, add the following to your LaunchBar configuration:

http://lists.psu.edu/cgi-bin/wa?S2=MACENTERPRISE&q=*&s=&f=&a=&b=

I added it in my personal search templates for UTF-8, named it “MacEnterprise list archives,” and saved it in my LaunchBar configuration. This makes it much faster to find topics that have appeared on the MacE list, because they are a few keystrokes away. LaunchBar substitutes your encoded search terms for the asterisk after the “&q=” text, and that’s where the magic lies.

Is that site running Drupal, curl edition

The Lullabot Web site has a clever way to help answer the question of “Is that site running Drupal?” Angie Byron mentions that the HTTP “Expires” header returned by Drupal corresponds to a specific default date. Look for that date in the HTTP headers, and you can make a reasonable guess that a site is a Drupal site — or at least one that hasn’t modified one of the core files.

Some commenters posted notes about how to do the same thing with wget and then curl. I expanded on the curl instructions to make them a little more robust (especially in the case of redirects or URL rewriting), and here’s the result:

$ curl -fsIL http://jaharmi.com/ 2>&1 | grep -q -m 1 "Expires: Sun, 19 Nov 1978 05:00:00 GMT" && echo "Yes, this appears to be a Drupal site." || echo "No, this does not appear to be a Drupal site."
Yes, this appears to be a Drupal site.

Navigating through files with less

It’s taken about a decade but I finally read the man page for “less.” Here are some important keyboard commands for navigating through files with it that I wanted to note for my own future use. If someone else gets a benefit from this, great, but it’s already helping me jump through man pages with more ease. (And it gave me an opportunity to write a post with a really ambiguous title.)

Key Function
f Move forward one screen
b Move backward one screen
j Move forward one line
y Move backward one line
= Show the number of lines and your progress through the file
< Move to the beginning of the file
> Move to the end of the file
% Scroll to the position in the file represented by the number before the percent sign

These commands had eluded me for a long time, even though it would have been great to know them. After all, less is the default pager in Mac OS X. Thanks to the wonders of air travel, I had some time to read some off-line documentation.

Of course, I’ve long used “/” followed by some text to search through man pages, and that’s worth knowing if you don’t already. One useful trick I picked up was the search “/^EXAM” (props to Adam for mentioning the caret and making my recipe one character longer, but more specific) to search for the examples section.

Syndicate content