Bash completion with aptitude aliases


  1. If I used my alias for installing an application (inst application), I would have to know the full application name because I would not have bash completion. This was very annoying when installing libraries because they often have weird version strings tacked on to their ends.
  2. If I used the full command (sudo aptitude install application), I would have bash completion and would therefore not have to know the whole application name. I could simply type libxul and get libxul0d.

On one hand, I would type a short command plus a complected application name, on the other I would type a long command and a simple application name. I wanted to be able to type a short command with a simple application name.


I wrote my own bash completion rules. They are based on the default aptitude bash completion rules but customized for aliases.

# Install Completion
        local cur dashoptions
        dashoptions='-S -u -i -h --help --version -s --simulate -d \
                     --download-only -P --prompt -y --assume-yes -F \
                     --display-format -O --sort -w --width -f -r -g \
                     --with-recommends --with-suggests -R -G \
                     --without-recommends --without-suggests -t \
                     --target-release -V --show-versions -D --show-deps\
                     -Z -v --verbose --purge-unused'
        if [[ "$cur" == -* ]]; then
            COMPREPLY=( $( compgen -W "$dashoptions" -- $cur ) )
                COMPREPLY=( $( apt-cache pkgnames $cur 2> /dev/null ) )
        return 0
        local cur dashoptions
        dashoptions='-S -u -i -h --help --version -s --simulate -d \
                     --download-only -P --prompt -y --assume-yes -F \
                     --display-format -O --sort -w --width -f -r -g \
                     --with-recommends --with-suggests -R -G \
                     --without-recommends --without-suggests -t \
                     --target-release -V --show-versions -D --show-deps\
                     -Z -v --verbose --purge-unused'
        if [[ "$cur" == -* ]]; then
            COMPREPLY=( $( compgen -W "$dashoptions" -- $cur ) )
                COMPREPLY=( $( _comp_dpkg_installed_packages $cur ) )
        return 0
complete -F _aptitude_all $default inst
complete -F _aptitude_all $default upgrade
complete -F _aptitude_all $default apt-info
complete -F _aptitude_all $default apt-changes
complete -F _aptitude_all $default apt-download
complete -F _aptitude_installed $default uninst
complete -F _aptitude_installed $default reinst
complete -F _aptitude_installed $default purge

Just copy it into a file such as ~/.bash_completion and source the file in your ~/.bashrc by adding ". ~/.bash_completion".

Change/Add/Remove the aliases at the end of the file. The lines that start with complete -F _aptitude_all complete any available or installed package and lines that start with complete -F _aptitude_installed complete only installed packages.

inst, upgrade, apt-info, apt-changes.... are my aliases. You must use YOUR ALIASES for this to work. To add aliases, read this.

Grdc - A very good graphical VNC viewer for the average linux user


After finding myself frustrated with Vinagre's (GNOME's standard VNC viewer) lack of ssh tunneling support I began looking for an alternative. I finally found it: Grdc.

Grdc supports both VNC and RDP. Grdc can tunnel both connections over ssh for security. The ssh tunneling supports key based or password based authentication and allows the user to select a custom server and port (if they differ from the defaults).

Grdc's user interface is much simpler than that of Vinagre. It allows the user to create and save custom connections and organize them by groups. Its connection quality settings are, unlike many remote desktop programs, quite simple. The user simply chooses the quality and the number of colors. Grdc also has a panel applet for the gnome-panel that lets users connect to their saved connections through a simple menu.

Another interesting feature is the "VNC Incoming Connection" protocol. This protocol lets users create new VNC servers with custom ports and passwords on the fly. This is especially useful if a user wants to let a remote user temporarily control their desktop.

Grdc does not support everything. It does not support tabbed connections like Vinagre but, in my opinion, tabbed connections are overkill for most users. It also does not support browsing a network for VNC connections with avahi as Vinagre does. This feature would be useful for administrators but is somewhat useless for the average user because most users will access the computer from the internet, not the LAN, and thus avahi support would be pointless.

Overall, Grdc is good for remote, internet traversing connections because of its ssh support and is useful to the average user because of its simplicity. Vinagre is still a better VNC client for administrators that have to manage many computers over a LAN because, on a LAN, encryption is usually unnecessary while avahi support is helpful and, when managing multiple computers, tabs are very helpful.

For screenshots see the SourceForge Screenshot Page


As of the writing of this post, the version of Grdc in the ubuntu repositories is woefully out of date and does not support ssh tunneling. Therefore one should use the deb provided by the project maintainers on sourceforge. Simply download the grdc deb (link below) and install (usually just double click). The grdc-gnome package is the gnome-panel applet and the grdc package is the main program.



-- Edit: I have packaged a 64bit version. Download here.

-- Edit 2: The 64bit version of grdc-gnome (the panel applet) for karmic seems to work in jaunty. Download here.

How to record one's linux computer with pulseaudio

I posted a simple tip to an user (mxc) explaining how to record a skype conversation and felt that others might find the information useful. Here is an elaborated explanation of how to record the sound from a linux computer.

  1. Install pavucontrol and the gnome-sound-recorder (in the gnome-media package).
  2. Open the gnome-sound-recorder and start recording
  3. Open the pulseaudio volume control and switch to the recording tab
  4. Click on the down arrow of the "gnome-sound-recorder" Record Stream, Select "Move Stream" and move the stream to the "Monitor" stream for your sound card.

This should record all sound from your computer if you are using pulseaudio. I have not tested this with skype but it should work. feed fetcher script

Attached is a simple feed fetcher script written in python. It is a console program and has no gui. It will display the same content as would appear on a users homepage for a given user. Edit the configuration at the head of the script before use.

It works well with conky; simply add ${exec python /path/to/} to your conky file and it will update whenever your conky refreshes. If your conky config is set to update very frequently, please use ${execi interval /path/to/} so that you are not constantly polling's server.

Edit: Updated script to correctly encode text and to include replies. Edit2: Inline script to fix broken link.


# -*- coding: utf-8 -*-

# Copyright (C) 2008 Steven
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <>.

# Blog:

import feedparser
import textwrap
import unicodedata
### SETTINGS ###
# Username (lowercase)
USER = "stebalien"
# Width in charictars of output
WIDTH = 50
# Number of posts to display
POSTS = 10

# Indent of posts


def formatPost(string):
    #string = string..replace(unicode("“", "utf-8"), '"').replace(unicode("”", "utf-8"), '"').replace(unicode("…", "utf-8"), '...').replace(unicode("’", "utf-8"), "'")
    string = unicodedata.normalize('NFKD', string).encode('ascii','ignore')
    parts = string.partition(':')
    return parts[0] + parts[1] \
    + "\n" + wrapper.fill('\n' \
    + parts[2]) \
    + "\n\n"
wrapper = textwrap.TextWrapper()
wrapper.subsequent_indent = ' '*INDENT_FIRST
wrapper.initial_indent = ' '*INDENT_REST
wrapper.width = WIDTH
# Get and display feed
all_feed = feedparser.parse("" + USER + "/all/rss")
reply_feed = feedparser.parse("" + USER + "/replies/rss")

n = 0
i = 0

while ((i+n) < POSTS):
    while (reply_feed.entries[n].updated_parsed > all_feed.entries[i].updated_parsed):
        print "> " + formatPost(reply_feed.entries[n].title)
    print "  " + formatPost(all_feed.entries[i].title)

Banshee Plugin for mumbles

I Just wrote a banshee plugin for mumbles. It works much better than banshee's default notification daemon integration. Clicking on the notification brings banshee to the front. Install it like you would any other mumbles plugin (see two posts back or look for instructions on the mumbles homepage).

Plugin (python 2.5) + Source: banshee-plugin_mumbles.tar.gz

Change the notification icon in Mumbles without creating a plugin.

I have noticed that several people have asked how to change the notification icon on mumbles without creating a new plugin.This is actually very simple: use the generic DBus plugin with dbus-send. I believe that this tutorial requires the SVN version but I may be mistaken. First add a new section to your DBus plugin configuration file. If you do not have this configuration file, copy the sample one from the mumbles source tarball (found on the project's homepage). The file is called dbus.conf.sample. Copy this file to ~/.mumbles/dbus.conf. The new section is as follows:

enabled = true
interface = org.program-or-script-name.DBus
path = /org/program-or-script-name/DBus
signal = your-signal
icon = your-icon.png

Put your-icon.png in the ~/.mumbles/plugins/icons/ folder.your-signal is your name for the alert. None of these variables are important but they must be consistent.

After doing the previous and restarting mumbles, run this command:

dbus-send /org/program-or-script-name/DBus org.`*program-or-script-name*`.DBus.your-signal string:"Title" string:"Message"

Make sure that you replace all necessary variables. This will display a mumbles popup with your custom icon, title, and message. You can also specify a click action using launch = action.

Mumbles with gmail

I have been playing around with mumbles lately and have written a gmail plugin for anyone interested. Mumbles is a notification system that works very much like growl for the mac. The latest SVN version can even replace the gnome notification daemon (but not very well). While still in its infancy, this project shows a lot of promise. I based the plugin on the evolution tutorial on project's homepage. I based the script on this script (with many modifications). When you click on the notification popup, evolution will launch (you can edit the source to change the program). The script requires python-feedparser.

Plugin, Source, and Script package: gmail-plugin_mumbles.tar.gz

Installing the precompiled plugin:

Do step 2 from the next section. Now copy the plugin to ~/.mumbles/plugins/.

Installing the plugin from source (adapted from dot_j's ~~tutorial~~ (gone)):

1. Download the source

Download the package and extract. Then open a terminal window inside the plugin-source folder.

2. Create the directory structure and choose an icon

Run the following command:

mkdir -p ~/.mumbles/plugins/icons 

Then either run this to use the default evolution icon...

cp /usr/share/icons/hicolor/22×22/apps/evolution.png ~/.mumbles/plugins/icons 

Or just copy your desired icon into the plugins/icons folder and rename it to evolution.png. This is unnecessary if you already have the evolution plugin.

Build and install the plugin

cd ~/gmail_plugin
python bdist_egg

This will use our file to create our plugin. After it runs, you should see a file named GmailMumbles-0.1-py2.5.egg in the dist directory that was created by the build process. Here the -py2.5 part of the filename refers to what version of python you are using (it may vary, but if you are able to start mumbles, should not matter).

The .egg file is our plugin, so the only thing left to do is copy that to the mumbles plugin directory.

cp dist/GmailMumbles-0.1-py2.5.egg ~/.mumbles/plugins

Installing the script:

Find the script in the package and edit the username and password variables. Run this script with python /path/to/ (replace /path/to with the path to the script). By default, this script will check for new email every 2 minutes and alert the user of new mail.

BTW: This script does not safely store the username and password. I may, in the distant future, make this script work with gnome-keyring but this is not likely. I hope that mumbles will soon get better notification-daemon support so that I can go back to using mail-notification.

OpenID: More accepters, less providers.

I am noticing a very annoying and self-defeating trend with OpenIDs. The main purpose of OpenID is to allow people to have one login for multiple sites. OpenID is pointless if few sites accept it. This problem will correct itself eventually as more sites adopt OpenID. The biggest problem is the number of sites providing and not accepting OpenID. This defeats the whole purpose of OpenID. It is pointless to have a myriad of choices for OpenIDs if you can't use them anywhere. Multiple OpenIDs for multiple sites just means multiple logins which is the very thing that OpenID is supposed to fix. I hope that many sites *ahem blogger* will soon start accepting OpenIDs as login credentials instead of just providing them.

General bug reporting rant

I am starting to see this very often and find it very annoying: people report a bug, later they find a preexisting report for the same bug, they then mark that preexisting bug as a duplicate of their bug. I end up getting lots of "this bug has been marked as a duplicate of bug x" emails and this is VERY annoying. To prevent this people need to rigorously check for a preexisting report. Second, when you find two duplicate bugs, search the bug tracker for any more duplicates and mark all of the newest duplicates as duplicates of the oldest bug. This prevents chains of duplicates which in turn maximizes the efficiency of the bug reporting and fixing process.



 report 1     ->    report 2     ->     report 3     ->     report 4
    |                  |                   |                   |
Commenters         Commenters           Commenters         All commenters
from report 1      from reports 1-2     from report 1-3


report 1 ----\
 commenters 1 \
report 2 ------> report 4
 commenters 2 /   all commenters
report 3 ----/
 commenters 3

In the chained version commenters move from report to report wasting comments on bugs that will probably never be seen again after being marked a duplicate. In the non-chained version commenters move directly from the duplicate to the final (and oldest) bug report wasting as few as comments possible on the duplicates.