Kir: find commands by describing them from the shell

2012 November 17

When doing system administration to fix a crash on some Unix-based server, I have run several times into the issue of trying to remember how to perform a certain task, but not remembering the exact sequence of commands. After that, I am always doing the same thing, and I have to resort to do a search on Google to find the commands I need. Those tasks are generally not frequent enough to be worth it to memorize the commands or create a script, but frequent enough for the process of searching to become really annoying. It’s also a productivity issue since it requires me to stop the current workflow, open a web browser and perform a search. For me, those things include tasks such as “how to find the number of processors on a machine” or “how to dump a Postgresql table in CSV format.”

I thought that it would be great to have some piece of code to just be able to query Google from the command-line. But that would be a mess, as for each query I would need a simple sequence of commands that I need to type, and not a blog article with fluffy text all around which is what Google is likely to return. Also, I thought about using the API of commandlinefu.com to get results directly from there. So I did a small Python script that performs text search that way, but the results were never exactly what I was looking for, since the commands presented there have been formatted by people who do not have the exact same needs I have. This is what brought me to implement Kir, a tiny utility to allow for text-search directly from the command-line and give the exact list of commands needed.

How does Kir work?

For instance, I never quite remember how to get the version of Ubuntu installed on a system. Possible commands for that are: lsb_release -cs, cat /proc/version, and cat /etc/issue. So here is what I do:

  1. Identify that I am looking for the same set of commands over and over again. Here it’s looking for a way to get the version of Ubuntu.
  2. Find the commands I need to type in. Here, lsb_release -cs, cat /proc/version, or cat /etc/issue.
  3. Define which keywords I am likely to use when I will look for this information in the future. In that case, I think that the following keywords define the problem quite well: distribution, linux, version, distro, ubuntu.
  4. Add all this information to the Kir configuration file, in ~/.kirrc like this:
rule: distribution, linux, version, distro, ubuntu
lsb_release -cs
cat /proc/version
cat /etc/issue

The first line tells Kir that a new “rule” is starting, with the keywords “distribution, linux, version, distro, ubuntu”. The following lines are the information that I was to be able to read whenever I am looking for those keywords. So now when I type:

$ kir linux version
I am getting:
3 results found
Best result:
*** 3: distribution version distro ubuntu linux
----------------------------------------------------------------
lsb_release -cs
cat /proc/version
cat /etc/issue
****************************************************************
Other results:
----------------------------------------------------------------
*** 4: info version package linux dependencies ubuntu
*** 12: svn version old previous

The best matching result is displayed first, with its full corresponding text. Then, other possible results are displayed, based on what I have put in my .kirrc file. Each result line starts with a number for the entries, here the numbers are 3, 4 and 12. If I want to get an item with its number, for instance #4, I can do it with:

$ kir 4

and I am getting this:

sudo apt-cache showpkg package-name

Note: this is because I added a rule that gives me, for Ubuntu, the command to the list of packages a specific package depends on.

Installing Kir on your machine

Installing Kir is extremely simple, as it’s just a tiny Python script. Note that since Kir is using sqlite3 for text search, you will need Python 2.5 or above. The steps are as follow:

  1. Get all the files from the Github repository: https://github.com/goossaert/kir
  2. Rename the kirrc-example file to .kirrc and put it in your home directory
  3. Create an alias for the kir command in your ~/.bashrc or ~/.profile file, like that : alias kir="python /path/to/kir.py". Or you can call this alias whatever you want instead of “kir”.
  4. Change the variable PATH_CONFIG in your kir.py file to point to the path of your .kirrc file. To make sure kir.py finds the file, use an absolute path, and not the ~ character to refer to the home director.
  5. Now you can start creating your .kirrc file, below is an example. You can also include notes about some tasks that you are often doing (here there is a rule with IP addresses of some servers, and a not to remember to restart to other servers after performing a specific task).
  6. In the .kirrc configuration file, the text referring to a rule will be all what’s below the rule and before the next rule. Empty lines will be skipped. the # character can be used to comment lines, and that

Example of .kirrc file:

rule: distribution, linux, version, distro, ubuntu
lsb_release -cs
cat /proc/version
cat /etc/issue

# this rule is for the task of setting up new nodes
rule: server, ip, address, hosts, hostnames
production: prod4
integration: integration2
dns server: 3.3.3.3

and remember to restart all nodes after changing the parameters

rule: dependencies, linux, package, info, ubuntu, version
sudo apt-cache showpkg package-name

# better than using wget
rule: download, resume, scp, partial, get, wget
rsync -vrPt -e ssh host:/remote_path/* /local_path/

Note that you can use Kir to store any kind of information that you may need in while you are using your shell. This doesn’t have to be a sequence of commands. For instance in the file above, I have a rule that contains the hostnames of some servers, along with a note at the very end (remember to restart the servers). These could be the hostnames of servers that you often use for a specific task, and don’t want to have to remember.

With Python 2.4 or below

You will need to install a replacement for sqlite3, like PySqlite. You can find this package here: http://trac.edgewall.org/wiki/PySqlite. Then, replace the line import sqlite3 in kir.py by from pysqlite2 import dbapi2 as sqlite3, all you’re all set!

No comments yet

Leave a Reply

Note: You can use basic XHTML in your comments. Your email address will never be published.

Subscribe to this comment feed via RSS