Thursday, April 03, 2008

Command Line Bookmarks

I wish I'd known about this tool years ago. Today I discovered a little utility called cdargs. Basically it lets you browse your directory tree very quickly, and allows you to create bookmarks to your most often used directories.

The bookmarks are stored at ~.cdargs in a simple format that's easily edited whenever you want to modify them, but I'm getting ahead of myself now...

cdargs has a directory browsing tool which is invoked by the cv command. In this tool, you can use arrow keys, Vim bindings, or even Emac bindings to navigate. Pressing a on a directory in the browser adds it as a bookmark, and pressing Enter opens it back in the shell. To see more of the available commands, press H or ? in the browser.

Outside, back in the shell, you can copy files and move files to your bookmarked directories using the cpb and mvb commands respectively. For example, cpb foo bar will move the file called foo from the current directory to the directory that I have bookmarked as bar. You guessed it, cdb bar would change you to the directory bookmarked by bar as well.

This tool has several more features as well, but I'll leave those up to you to discover. The man page is a good read, and I don't want to take all the fun away from you :). The only problem I can see with this tool is that it may be difficult getting used to the different commands. Typically the commands they replace or supplement are used quite quickly. By the time I stop to recall the applicable cdargs command I've waited too long. If I can get past that, there's no doubt I'll get some good use out of this one.

Saturday, March 15, 2008

Change the Solaris Shell to Bash

For those of us that are stuck working in Solaris environments with either csh or ksh as the default shell, there is hope. Some of these environments have the chsh command to change shells, but for those that don't, here is how to change your shell to bash. First of all, make sure it is available on your system. It's typically found in /bin/bash. If it's there, you can edit your ~/.profile to make it run the new shell when you login.

IMPORTANT: Before doing this, open two separate shells. Keeping one open and unaltered is a good way to recover if something goes wrong in this process. If you break something and can't log in, you may piss off your system admin when you have to call him to fix it for you. Leave one of these open shells alone during this process.

In one of your open shells, add the following two lines to the bottom of your ~/.profile.

export SHELL=/bin/bash
exec $SHELL

You can now log out of that shell and back in again to see if it worked. If so, all went well and you can close the other shell. If not, use your "safety" shell to repair your ~/.profile so that you can log in again.

Sunday, February 24, 2008

Google Makes Me Stupid

Does anyone else find that sometimes their first response to a problem is to search Google? I just had the good ol' 500 Internal Server Error in an Apache request and immediately I searched Google for assistance. Given that the web server in question was my own, the reasonable person would first check the server error.log, but I'm apparently not that guy. In my defence, it didn't take long for me to remember this, but still, Google was my initial reaction.

A quick check of said log file suggested an .htaccess issue, and now all is well. Perhaps we're (I'm?) becoming too dependant on our search engine overlords...

Vim and Perforce

My employer has used Perforce as a VCS for several years now. Perforce itself maintains integration plugins for Eclipse, but of course not for editors like Vim so it's up to the community to do so. Lucky for me, extremely capable Vim scripters like Hari Krishna Dara also use Perforce from time to time :). This is the same author who brought us the genutils.vim plugin as well as many other powerful scripts as his vim profile lists. Among these is a fantastic perforce script set that I downloaded to try about a week ago. It was more than I'd hoped for.

This is a very featureful Perforce integration script with a complete set of menus (although I have menus hidden in my vim) and commands. I'm not sure whether the author still uses it or not however because there was a bug in spec-based commands that broke it pretty badly. Of course, there is the possibility that I'm using it incorrectly too. Regardless, I've "fixed" a couple of these bugs and emailed the author with a patch. I also uncovered a bug in the genutils.vim script that it depends on. The author also mentions this in the script page for the Perforce plugin:

Lately, I am not finding enough time to add features to this, so if anybody is
interested to help me add new features or even take over the responsibility, you
are very much welcome.

Although I sent him a small patch in his Inbox, he may not have the time to make a bug fix release, so I've made a little bazaar branch of the complete script on my own little server here for the time being. This branch includes the fixes for a couple of little bugs, and some extra syntax hinting for pending changelists and closed jobs. Aside from that, it's unaltered. You can get it using this command, assuming you have bzr installed.

$ bzr branch vim-perforce

I might add a few features or commands that have been included in the p4 client since his last release of the script at some point too. Depending on his email reply (if he replies) we'll see if he'd like my changes included in his next release or not. My additions unfortunately won't be of the same quality as the stuff he's already written. I'm not exactly a seasoned vim-scriptor...

All in all, it's a fantastic script. Check it out if you use Vim with the Perforce VCS, and big kudos and thanks go out to the original author!

Tuesday, February 19, 2008

Stumped by a Captcha

Does anyone see the security code in this captcha?

Bad Captcha Image

This one has me stumped...

Monday, February 18, 2008

GnuCash Broke My Ledger :(

For the past year and a bit, I've been happily using GnuCash with Ledger and it had been a fantastic duo. Several days ago, I upgraded to GnuCash 2.2.3 and the combo doesn't work so well anymore. The problem stems from an internal change that adds a "Root Account" as the top level account in the tree. To say the two don't work together anymore might be a little harsh, but they at least don't work as well together as they used to. For example, this used to work to get a quick net worth:

$ ledger bal ^ass ^liab

The ^ass and ^liab bits are regular expressions that match all accounts that start with the letters ass and liab (assets and liabilities) respectively. This would result in a little chart showing my total assets minus my total liabilities, since "Assets" and "Liabilities" used to be top level accounts. Now with the new structure, these accounts are no longer roots. Instead they look like "Root Account:Assets" and "Root Account:Liabilites". Long story short, this new "Root Account" is the only top level account. To make matters worse, the bloody account name has a space in its name, and we all know how well spaces work on the command line...

Needless to say, the combination became a lot less useful with this update. I'm not sure whether to downgrade to GnuCash 2.0 or not. What a shame.

Saturday, February 16, 2008

Changing the Default Text Editor in GNOME

The "Preferred Applications" menu item in GNOME runs a little app that allows you to change some of the default programs used for various tasks like web browsing, music playing etc. One thing that's been missing for me is the ability to change the default text editor. Sure you can open up Nautilus, right click on a text file, and chose that way, but there are many types of text files, and they are each treated independantly.

Recently I discovered the ~/.local/** path. I'll use gvim as an example for this excersise. This is the ticket for swapping default editors once and for all! First, use the method described above (the right click in Nautilus way). Now you should have a ~/.local/share/applications/gvim.desktop file. That's good. Next, create a ~/.local/share/applications/defaults.list file, and put this in it:

    [Default Applications]

The contents above were taken from my own system wide /usr/share/applications/defaults.list, just with :%s/gedit/gvim/. This should at least cover the file types that gedit keeps popping open for. You could always modify the system wide defaults.list, but be prepared to lose those changes during your next update. Also, since the gvim.desktop file already existed in my local home path, I never tried just copying the one from /usr/share/applications. That might work too.

I can't believe I've been using GNOME for so long and never knew this :(

Tiny Tiny RSS Feed Reader

Lately, I've been missing something in a feed reader. In the past six months or so I've tried a plethora of different readers of different forms. I tried the desktop application style like Lifrea, the online flavors like Google Reader, and the Firefox extension kind like Sage. All have their benefits, but also disadvantages. For example offline readers make it a pain when one uses different machines, online reader services felt slow or sluggish, and cluttered. Not to mention they can't be modified.

I forget now how I heard about Tiny Tiny RSS now, but if I remember I'll update this post with well deserved props. This thing is perfect in my opinion. It's fast, it's open source, it's written in PHP/MySQL, and it's pretty feature complete. Even setup was a breeze and went without a hitch.

The interface is very clean and well organized. One can tell pretty early that some of the interface ideas in TTRSS were inspired by Google's great GMail interface like the ability to star articles as well as the familiar actions list, and in fact it very much has the feel of using your typical desktop email application. This reader can run in either single or multi-user modes, and you can publish your feeds and articles with others with a single click.

I'll not provide a list of features here since they do a pretty good job of that on their website. If you are not in love with your current reader, I very strongly suggest this gem!

Sunday, January 20, 2008

It's Been Almost a Year

I'm about as interested in writing a reasons-for-not-posting-for-a-year blog entry as you are in reading one. Instead, I'll just say that since my last post I've gotten a job and I've gotten my wife pregnant.

The baby is due in May!

P.S. I really should take that terrible picture of my head down from up there...

Wednesday, January 24, 2007

Beryl and the ATI IGP 340M

I can't believe nobody told my that Beryl would work with my cruddy 340M graphics chip. I threw caution to the wind today and tried it only to find out that it worked quite nicely! Sure, it's not as smooth as on my desktop machine with an NVidia chip, but it is very usable and pretty. I basically just followed these instructions and boom. All was well. Oh, I also changed the driver in my /etc/X11/xorg.conf file to radeon from ati.

Anyways, here is the cool screenshot...

Thursday, January 04, 2007

Rotating Backups with Rsync

The Christmas break was pretty good, with one exception. The hard drive on my laptop gave me some serious grief. Long story short, I wiped it, made new partitions, and reinstalled the OS. Now luckily, I was smart enough to keep partial daily backups on my server for just these occasions so nothing too important was lost (thesis). However, the keywords here are partial backups. This means that most of my settings and non-crucial data was not backed up, and that has turned out to be a bit of a drag.

Anyways, the hard drive appears to be functioning correctly now, I purchased an el cheapo (some of us never learn) external drive, and I'm looking to do full backups of my $HOME directory from now on. A quick search took me to the concepts outlined here. This scheme is pretty clever, is suprisingly fast, and very efficient on drive space. The result is a simple Python script that seems to do the trick. Well, it's mostly Python with a bunch of Bash calls via os.system(), but close enough.

Basically, it uses rsync to synchronize data over an ssh connection to my remote server. That remote machine has the external drive attached and mounted. Given a remote destination directory, it creates a series of backup directories based on the local machine's hostname. For example, my laptop's hostname is sigma and the script creates the directories sigma/sigma, sigma/sigma.1, sigma/sigma.2 etcetera all the way up to sigma/sigma.7. These numbered directories contain snapshots of the data back seven runs. So if you run the script once per day, you have a snapshot for the past seven days. Instead of storing all of the data seven times however, it uses hard links to save space. I'll let you read up on this concept here if you are interested.

Several assumptions are made in this script. One is that you have passwordless ssh logins setup correctly. Also, the script requires a configuration file called ~/.backuprc where several custom settings are stored and read. Here is an example of such a file.

EXCLUDES = *.iso,*.avi,*.mpg,*.mp3,*.ogg,*.wma,*.wmv,*.mov,*.LNK,*.LCK
LOG_DIR = ~/.backup_logs/
DEST_PATH = /media/backup_drive/home_backup/

The variables in this file break down as follows...

  • EXCLUDES: A comma separated list of patterns matching files that are not to be backed up.
  • SOURCES: A comma separated list of directories to be backed up. The example instructs the script to back up the user's entire home directory.
  • DEST_HOST: The host of the remote server where the backups will be sent.
  • LOG_DIR: The location where log files should be saved.
  • DEST_PATH: The destination on the remote machine where the backups will be stored.

I put an entry in my user's crontab to run the script at 12:05pm every day. The entry looks like this:

5 12 * * * /home/dcraven/bin/backup

The script is located in my ~/bin directory. If you need help with cron, have a look at this tutorial. Keep in mind that when run this way, cron will only execute the command if the machine is on when it is scheduled. It will not automatically run when the machine is started when a scheduled time is missed. For this behaviour, look into /etc/cron.daily and friends.

At the moment, all of these settings are required in the file. At some point I might write something a little more robust and clean, but for now this works and I have other things that should be given a higher priority.

Wednesday, December 20, 2006

Searchable Tags in td

I'm starting to really like writing console apps in Python. To add a feature takes no time at all since there is little UI to deal with. Over the last hour I've implemented tagging for your tasks in td. Tags for searching and grouping items seem to be pretty popular in current applications, so I thought why not a todo list manager? I think I like this better than the projects I implemented a couple of weeks ago. The projects stuff is of course still available and fully functional, I just don't think I'll be using it as much anymore because the new tags are much handier. In fact, you can still use both at the same time. Here is how the new tags command works...

When you create a new task, a group of tags can be associated with it by including a space separated list, enclosed in square brackets, in the task summary.

$ td add [tag1 tag2 tag3]This is a new task.

Now, if I want to see what tags are being used:

$ td tags
--> Available tags:
--> tag1(1) tag2(1) tag3(1)

Issuing the new tags command with no arguments lists all tags, and the number of tasks with that tag. If you want to see a list of tasks by tag:

$ td tags tag1
-->  #   P H  Created    Description
-->  1        12/20/06   This is a new task.

Maybe you want to see a list of tags that are associated with a specific task?

$ td tags 1
--> [tag1 tag2 tag3]

Want to remove the "tag2" tag from that task? No problem...

$ td tags 1 -tag2
$ td tags 1
--> [tag1 tag3]

Let's remove "tag3" now, and add "newtag" to this task:

$ td tags 1 -tag3 +newtag
$ td tags 1
--> [tag1 newtag]

You can still use the replace command to replace all of them at once.

$ td replace 1 [foo bar]This is a new task.
$ td tags 1
--> [foo bar]

And of course you can easily combine hidden status, tags, and projects all at once.

$ td add .[tag1 tag2] p:MyProject This is yet another new task.
$ td tags tag1
-->  #   P H  Created    Description
-->  2     *  12/20/06   This is yet another new task.
$ td project MyProject
-->  #   P H  Created    Description
-->  2     *  12/20/06   This is yet another new task.

Notice the "H" column in that output indicates whether the task in the list is hidden or not. That column was recently added to both the tags and the project output. These changes are committed and pushed to the bazaar repository that I spoke of in my last post. Don't forget to email me the bugs!