<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Unmaintainable &#187; shell</title>
	<atom:link href="http://unmaintainable.wordpress.com/category/shell/feed/" rel="self" type="application/rss+xml" />
	<link>http://unmaintainable.wordpress.com</link>
	<description>Scripting, Software Engineering and Stuff in Between</description>
	<lastBuildDate>Sun, 22 Nov 2009 09:05:47 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='unmaintainable.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/6f90ae5619dfc90140df401ac60575d2?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>Unmaintainable &#187; shell</title>
		<link>http://unmaintainable.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://unmaintainable.wordpress.com/osd.xml" title="Unmaintainable" />
		<item>
		<title>Quick Tip #2: Set Operations Using Shell Tools</title>
		<link>http://unmaintainable.wordpress.com/2009/08/19/set-operations-using-shell-tools/</link>
		<comments>http://unmaintainable.wordpress.com/2009/08/19/set-operations-using-shell-tools/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 08:33:23 +0000</pubDate>
		<dc:creator>mafr</dc:creator>
				<category><![CDATA[shell]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[quick tips]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://unmaintainable.wordpress.com/?p=300</guid>
		<description><![CDATA[Everybody knows that Unix shell utilities are powerful. Even though they&#8217;re text-based, you can build a lot of useful things outside of the text domain. Today I&#8217;ll show you how to implement set operations. All we need are sorted files as input, with each file representing a set.

Let&#8217;s create some input files A and B:

$ [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=300&subd=unmaintainable&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Everybody knows that Unix shell utilities are powerful. Even though they&#8217;re text-based, you can build a lot of useful things outside of the text domain. Today I&#8217;ll show you how to implement set operations. All we need are sorted files as input, with each file representing a set.</p>
<p><span id="more-300"></span></p>
<p>Let&#8217;s create some input files <cite>A</cite> and <cite>B</cite>:</p>
<pre>
$ echo a b d e | tr ' ' '\n' &gt; A
$ echo a c e f | tr ' ' '\n' &gt; B
</pre>
<p><strong>Note</strong>: It&#8217;s an important precondition is that all input files are sorted! To avoid ugly surprises, the files mustn&#8217;t contain duplicates, but you would expect that from a set.</p>
<p>Since the input files are sorted, <strong>equality</strong> is trivial:</p>
<pre>
$ cmp A B
</pre>
<p>For use in scripts, the <em>silent switch</em> <cite>-s</cite> is useful.</p>
<p><strong>Intersection</strong>:</p>
<pre>
$ comm -12 A B
</pre>
<p>The <cite>comm</cite> utility outputs three columns per default: The lines unique to the first file, the lines unique to the second file and the lines appearing in both files. We turn off the first two columns leaving just the intersection.</p>
<p><strong>Union</strong>:</p>
<pre>
$ sort -m A B | uniq
</pre>
<p>The <em>merge switch</em> <cite>-m</cite> isn&#8217;t necessary for correctness, but it improves runtime for large files quite a bit. Unfortunately, not all sort implementations have it.</p>
<p><strong>Difference</strong>:</p>
<pre>
$ comm -23 A B
</pre>
<p>This only displays the lines unique to A, leaving the result of A minus B.</p>
<p>You can use the difference to get the <strong>complement</strong>. This requires a universe U first that we create using our union construct. The we subtract A from U:</p>
<pre>
$ sort -m A B | uniq | comm -23 - A
</pre>
<p>With only two files, this is just an inefficient way of subtracting A from B.</p>
<p><strong>Contains</strong> can be implemented using <cite>grep</cite>, but we have to be careful about false positives:</p>
<pre>
$ grep -Fx e A
</pre>
<p>The <em>quiet switch</em> <cite>-q</cite> is useful in scripts and may also reduce runtime because it exits as soon as the entry is found. This is still far less efficient than it could be if we had fixed size records and used interval halving.</p>
<p>More advanced operations like testing if one set is a subset of another are possible, too. Often you will also have to compare line counts using <cite>wc -l</cite>, but I&#8217;ll leave that as an exercise to the reader :)</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/unmaintainable.wordpress.com/300/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/unmaintainable.wordpress.com/300/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/unmaintainable.wordpress.com/300/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/unmaintainable.wordpress.com/300/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/unmaintainable.wordpress.com/300/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/unmaintainable.wordpress.com/300/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/unmaintainable.wordpress.com/300/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/unmaintainable.wordpress.com/300/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/unmaintainable.wordpress.com/300/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/unmaintainable.wordpress.com/300/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=300&subd=unmaintainable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://unmaintainable.wordpress.com/2009/08/19/set-operations-using-shell-tools/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/59c9677a3b9569af44561adab6c2a980?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mafr</media:title>
		</media:content>
	</item>
		<item>
		<title>Rsync Snapshot Backups Revisited</title>
		<link>http://unmaintainable.wordpress.com/2008/08/09/rsync-snapshot-backups-revisited/</link>
		<comments>http://unmaintainable.wordpress.com/2008/08/09/rsync-snapshot-backups-revisited/#comments</comments>
		<pubDate>Sat, 09 Aug 2008 15:45:45 +0000</pubDate>
		<dc:creator>mafr</dc:creator>
				<category><![CDATA[shell]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://unmaintainable.wordpress.com/?p=83</guid>
		<description><![CDATA[A while ago, I blogged about my self-made backup solution, a simple shell script using rsync to create snapshot backups. This wasn&#8217;t my first attempt at establishing backups for my private workstation but the most successful one so far. The backup takes less than 5 minutes for about 10 GB of data in my home [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=83&subd=unmaintainable&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>A while ago, I blogged about my <a href="2008/06/26/rsync-backups/">self-made backup solution</a>, a simple shell script using rsync to create snapshot backups. This wasn&#8217;t my first attempt at establishing backups for my private workstation but the most successful one so far. The backup takes less than 5 minutes for about 10 GB of data in my home directory. It&#8217;s a quick and painless process, and a repeating appointment in my calendar reminds me not to forget it.</p>
<p><span id="more-83"></span></p>
<p>A friend of mine (hey Mike!) liked the idea, bought an external USB drive and started to use the script, too. Being an experienced Unix user and hacker, he sensed room for improvement and we tweaked the script to handle errors more gracefully and to provide better diagnostics in case things go wrong. The script has about tripled in size since its original release, but with its 80 lines and comprehensive comments it&#8217;s still easy to extend and understand. Thanks a lot, Mike!</p>
<p>You can get <a href="http://musicbrainz.org/~matt/scripts/backup.sh">the script</a> and the <a href="http://musicbrainz.org/~matt/scripts/backup.rc">rsync filter file</a> from the usual place.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/unmaintainable.wordpress.com/83/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/unmaintainable.wordpress.com/83/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/unmaintainable.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/unmaintainable.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/unmaintainable.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/unmaintainable.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/unmaintainable.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/unmaintainable.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/unmaintainable.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/unmaintainable.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/unmaintainable.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/unmaintainable.wordpress.com/83/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=83&subd=unmaintainable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://unmaintainable.wordpress.com/2008/08/09/rsync-snapshot-backups-revisited/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/59c9677a3b9569af44561adab6c2a980?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mafr</media:title>
		</media:content>
	</item>
		<item>
		<title>Quick Tip #1: Implicit FIFOs in Bash</title>
		<link>http://unmaintainable.wordpress.com/2008/07/05/implicit-fifos/</link>
		<comments>http://unmaintainable.wordpress.com/2008/07/05/implicit-fifos/#comments</comments>
		<pubDate>Sat, 05 Jul 2008 07:22:47 +0000</pubDate>
		<dc:creator>mafr</dc:creator>
				<category><![CDATA[shell]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[quick tips]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://unmaintainable.wordpress.com/?p=64</guid>
		<description><![CDATA[One could assume that I have run out of material and retreat to safer ground, but far from it. From now on I&#8217;ll just throw in a few quick shell hacks hoping some of you don&#8217;t know them yet. So, here it goes &#8230;
Unix pipes are cool, but it&#8217;s quite a limitation that a program [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=64&subd=unmaintainable&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>One could assume that I have run out of material and retreat to safer ground, but far from it. From now on I&#8217;ll just throw in a few quick shell hacks hoping some of you don&#8217;t know them yet. So, here it goes &#8230;</p>
<p>Unix pipes are cool, but it&#8217;s quite a limitation that a program can only read from a single pipe. Sure, there are named pipes, but it&#8217;s a real pain to use them and we&#8217;d be leaving oneliner zone. Fortunately, recent versions of bash support implicit FIFOs that are created on demand by the shell. All you need is a bit of additional syntax.</p>
<p><span id="more-64"></span></p>
<p>Suppose you want to concatenate two compressed CSV files. The minor complication here is that you only want the header of the first file. With implicit FIFOs that&#8217;s easily possible:</p>
<pre>
$ zcat data_1.csv.gz | cat - &lt;(zcat data_2.csv.gz | sed 1d) &gt; out.csv
</pre>
<p>The sed(1) command deletes the first line of its input stream removing the CSV file&#8217;s header (one header should be enough in most cases). If you like symmetry, you can use this equivalent version:</p>
<pre>
$ cat &lt;(zcat data_1.csv.gz) &lt;(zcat data_2.csv.gz | sed 1d) &gt; out.csv
</pre>
<p>In another use case you might want to check which files are in directory <code>dir1</code> but not in <code>dir2</code>:</p>
<pre>
$ comm -23 &lt;(ls dir1 | sort) &lt;(ls dir2 | sort)
</pre>
<p>Try the following if you&#8217;re interested in where the FIFO is created:</p>
<pre>
$ echo &lt;(echo test)
</pre>
<p>There are implicit FIFOs for output, too, but I never found a good use case for them (maybe they&#8217;re useful for complex tee(1) constructs). For more information see section &quot;Process Substitution&quot; in your bash(1) man page.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/unmaintainable.wordpress.com/64/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/unmaintainable.wordpress.com/64/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/unmaintainable.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/unmaintainable.wordpress.com/64/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/unmaintainable.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/unmaintainable.wordpress.com/64/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/unmaintainable.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/unmaintainable.wordpress.com/64/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/unmaintainable.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/unmaintainable.wordpress.com/64/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/unmaintainable.wordpress.com/64/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/unmaintainable.wordpress.com/64/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=64&subd=unmaintainable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://unmaintainable.wordpress.com/2008/07/05/implicit-fifos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/59c9677a3b9569af44561adab6c2a980?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mafr</media:title>
		</media:content>
	</item>
		<item>
		<title>Parsing Command Line Options in Shell Scripts</title>
		<link>http://unmaintainable.wordpress.com/2007/08/05/cmdline-options-in-shell-scripts/</link>
		<comments>http://unmaintainable.wordpress.com/2007/08/05/cmdline-options-in-shell-scripts/#comments</comments>
		<pubDate>Sun, 05 Aug 2007 09:44:38 +0000</pubDate>
		<dc:creator>mafr</dc:creator>
				<category><![CDATA[shell]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://unmaintainable.wordpress.com/2007/08/05/cmdline-options-in-shell-scripts/</guid>
		<description><![CDATA[In programs written in C, parsing of command line arguments has always been done using the getopt(3) library function. This function has set the standards Linux/Unix users have come to expect from command line interfaces. Fortunately, there&#8217;s a getopt(3) equivalent for almost every programming language and the shell is no exception.

The getopts command available in [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=26&subd=unmaintainable&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>In programs written in C, parsing of command line arguments has always been done using the <code>getopt(3)</code> library function. This function has set the standards Linux/Unix users have come to expect from command line interfaces. Fortunately, there&#8217;s a <code>getopt(3)</code> equivalent for almost every programming language and the shell is no exception.</p>
<p><span id="more-26"></span></p>
<p>The <code>getopts</code> command available in all POSIX-compliant Bourne shell derivates (like bash, dash, or ksh) provides convenient command line parsing capabilities. It is a builtin accepting POSIX-style argument lists (as opposed to GNU-style, which is a bit more fancy) and should not be confused with the <code>getopt</code> utility.</p>
<p>For my shell scripts, I use the <a href="http://musicbrainz.org/~matt/scripts/shell-getopts">following template</a> to implement command line parsing:</p>
<pre>
#! /bin/sh

USAGE="Usage: `basename $0` [-hv] [-o arg] args"

# we want at least one parameter (it may be a flag or an argument)
if [ $# -eq 0 ]; then
	echo $USAGE &gt;&amp;2
	exit 1
fi

# parse command line arguments
while getopts hvo: OPT; do
    case "$OPT" in
	h)	echo $USAGE
		exit 0
		;;
	v)	echo "`basename $0` version 0.1"
		exit 0
		;;
	o)	OUTPUT_FILE=$OPTARG
		;;
	&#92;?)	# getopts issues an error message
		echo $USAGE &gt;&amp;2
		exit 1
		;;
    esac
done

shift `expr $OPTIND - 1`

# access additional parameters through $@ or $* as usual or using this loop:
for PARAM; do
    echo $PARAM
done

# EOF
</pre>
<p>More command line switches can be added to the loop. If you want to add an <code>-x</code> switch requiring an argument (<code>-x arg</code>) and a <code>y</code> flag without an argument, you would have to change the getopts call to <code>getopts hvo:x:y OPT</code> and add two case labels to the loop. Note that the colon indicates that an argument is required for a flag.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/unmaintainable.wordpress.com/26/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/unmaintainable.wordpress.com/26/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/unmaintainable.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/unmaintainable.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/unmaintainable.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/unmaintainable.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/unmaintainable.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/unmaintainable.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/unmaintainable.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/unmaintainable.wordpress.com/26/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/unmaintainable.wordpress.com/26/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/unmaintainable.wordpress.com/26/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=26&subd=unmaintainable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://unmaintainable.wordpress.com/2007/08/05/cmdline-options-in-shell-scripts/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/59c9677a3b9569af44561adab6c2a980?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mafr</media:title>
		</media:content>
	</item>
		<item>
		<title>Building RPMs Without Root Access</title>
		<link>http://unmaintainable.wordpress.com/2007/03/25/building-rpms-without-root/</link>
		<comments>http://unmaintainable.wordpress.com/2007/03/25/building-rpms-without-root/#comments</comments>
		<pubDate>Sun, 25 Mar 2007 09:51:05 +0000</pubDate>
		<dc:creator>mafr</dc:creator>
				<category><![CDATA[shell]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://unmaintainable.wordpress.com/2007/03/25/building-rpms-without-root/</guid>
		<description><![CDATA[This week at work I had the opportunity to build an RPM for some third-party software package.
My previous experiences with RPM date back to SuSE 5 almost ten years ago and I haven&#8217;t touched it ever since. Packaging for Debian or even NetBSD is mostly a painless process, so I hoped today&#8217;s RPM wouldn&#8217;t be [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=16&subd=unmaintainable&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>This week at work I had the opportunity to build an RPM for some third-party software package.</p>
<p>My previous experiences with RPM date back to SuSE 5 almost ten years ago and I haven&#8217;t touched it ever since. Packaging for Debian or even NetBSD is mostly a painless process, so I hoped today&#8217;s RPM wouldn&#8217;t be much different. Things worked out fine, except for one thing: RPM uses a well-known base directory (<code>/usr/src/packages</code> on SuSE) which only root can write to. Sure, you can pass ownership to another user, but without root access in the first place you&#8217;re out of luck.</p>
<p><span id="more-16"></span></p>
<p>Using <code>~/.rpmmacros</code>, users can define their own private staging area, but that&#8217;s no elegant solution either. Not even <a href="http://docs.fedoraproject.org/drafts/rpm-guide-en/index.html">The RPM Guide</a> came up with a usable receipe for this.</p>
<p>After some unsuccessful experiments, I decided to have a look at how python&#8217;s distutils solve this problem. With distutils, you can build RPMs from python packages (<code>python setup.py bdist_rpm</code>) without superuser privileges. That&#8217;s why I figured it had to be possible.</p>
<p>Distutils uses <code>rpmbuild</code>&#8217;s <code>--define</code> switch (undocumented in the man page) and the <code>_topdir</code> macro:</p>
<pre>
  rpmbuild -ba --define "_topdir /path/to/staging_dir"
     /path/to/staging_dir/SPECS/package.spec
</pre>
<p>Note that <code>/path/to/staging_dir</code> has to be an absolute path, leading to the directory which contains the same directory structure <code>/usr/src/packages</code> has. <code>`pwd`</code> can be used to avoid hardcoding the path. </p>
<p>From a script, I create the directory structure in my local working directory, copy source tarball and spec file to <code>SOURCES</code> and <code>SPECS</code> and execute <code>rpmbuild</code>.</p>
<p>The created RPM can then be found in the <code>RPMS</code> directory. </p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/unmaintainable.wordpress.com/16/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/unmaintainable.wordpress.com/16/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/unmaintainable.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/unmaintainable.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/unmaintainable.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/unmaintainable.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/unmaintainable.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/unmaintainable.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/unmaintainable.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/unmaintainable.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/unmaintainable.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/unmaintainable.wordpress.com/16/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=16&subd=unmaintainable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://unmaintainable.wordpress.com/2007/03/25/building-rpms-without-root/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/59c9677a3b9569af44561adab6c2a980?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mafr</media:title>
		</media:content>
	</item>
		<item>
		<title>Changing Directories Quickly</title>
		<link>http://unmaintainable.wordpress.com/2007/02/11/changing-directories-quickly/</link>
		<comments>http://unmaintainable.wordpress.com/2007/02/11/changing-directories-quickly/#comments</comments>
		<pubDate>Sun, 11 Feb 2007 15:00:38 +0000</pubDate>
		<dc:creator>mafr</dc:creator>
				<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://unmaintainable.wordpress.com/2007/02/11/changing-directories-quickly/</guid>
		<description><![CDATA[When you work with the interactive shell, there&#8217;s a common pattern that is used a lot: Copying or moving files to a directory and then changing to the target directory using cd. In these cases, you find yourself typing the name twice:

  $ cp file1 file2 file3 /very/long/path/name
  $ cd /very/long/path/name

Tab completion helps, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=14&subd=unmaintainable&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>When you work with the interactive shell, there&#8217;s a common pattern that is used a lot: Copying or moving files to a directory and then changing to the target directory using <code>cd</code>. In these cases, you find yourself typing the name twice:</p>
<pre>
  $ cp file1 file2 file3 /very/long/path/name
  $ cd /very/long/path/name
</pre>
<p>Tab completion helps, but for long names it&#8217;s still tedious.</p>
<p><span id="more-14"></span></p>
<p>One of my favourite tools, the <a href="http://musicbrainz.org/~matt/scripts/g">bash function <em>g</em></a> (&#8220;go&#8221;), shortens this to the following:</p>
<pre>
  $ cp file1 file2 file3 /very/long/path/name
  $ g
</pre>
<p>It works by getting the previous command from the bash history, treating the last argument as a directory and then going there. If the last argument is a file name, the <code>g</code> function tries to resolve it to a directory name by using the basename or stripping off common archiver suffixes like tar, tar.gz or zip.</p>
<p>The function is one of the most executed commands in my shell history. I also had a companion function which changed back to the previous directory, but since <code>cd -</code> is pretty short, too, it didn&#8217;t get used that often. To use it, <a href="http://musicbrainz.org/~matt/scripts/g">download the function</a> and simply copy it into your <code>~/.bashrc</code> file.</p>
<p>Note that this function works on bash only. I used to have a Korn shell compatible function, but it didn&#8217;t work as nicely as this one.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/unmaintainable.wordpress.com/14/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/unmaintainable.wordpress.com/14/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/unmaintainable.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/unmaintainable.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/unmaintainable.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/unmaintainable.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/unmaintainable.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/unmaintainable.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/unmaintainable.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/unmaintainable.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/unmaintainable.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/unmaintainable.wordpress.com/14/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=14&subd=unmaintainable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://unmaintainable.wordpress.com/2007/02/11/changing-directories-quickly/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/59c9677a3b9569af44561adab6c2a980?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mafr</media:title>
		</media:content>
	</item>
		<item>
		<title>Using D-Bus Introspection</title>
		<link>http://unmaintainable.wordpress.com/2006/12/19/using-dbus-introspection/</link>
		<comments>http://unmaintainable.wordpress.com/2006/12/19/using-dbus-introspection/#comments</comments>
		<pubDate>Tue, 19 Dec 2006 14:32:34 +0000</pubDate>
		<dc:creator>mafr</dc:creator>
				<category><![CDATA[shell]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://unmaintainable.wordpress.com/2006/12/19/using-dbus-introspection/</guid>
		<description><![CDATA[To control a D-Bus-enabled application, you need the interface definition to find out which methods are offered and which parameters they expect.
Of course, you can get the relevant interface definition from the application&#8217;s source distribution. But there&#8217;s an easier way: Ask the object in question via D-Bus to give you the interface description. All objects [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=7&subd=unmaintainable&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>To control a <a href="http://dbus.freedesktop.org">D-Bus</a>-enabled application, you need the interface definition to find out which methods are offered and which parameters they expect.</p>
<p>Of course, you can get the relevant interface definition from the application&#8217;s source distribution. But there&#8217;s an easier way: Ask the object in question via D-Bus to give you the interface description. All objects implementing the <code>org.freedesktop.DBus.Introspectable</code> interface offer an <code>Introspect()</code> method that returns an XML document describing the methods and their signatures.</p>
<p><span id="more-7"></span></p>
<p>Instead of python, we&#8217;ll use the <code>dbus-send</code> command line utility this time. The following command dumps the definition of rhythmbox&#8217; <code>/org/gnome/Rhythmbox/Player</code> object:</p>
<pre>
  dbus-send --session --type=method_call --print-reply
      --dest=org.gnome.Rhythmbox
      /org/gnome/Rhythmbox/Player
      org.freedesktop.DBus.Introspectable.Introspect
</pre>
<p>The service to query is <code>org.gnome.Rhythmbox</code> and the object&#8217;s interface is <code>org.freedesktop.DBus.Introspectable</code>. Note that for <code>dbus-send</code>, the method&#8217;s name (<code>Introspect</code> here) has to be appended to the interface. See the dbus-send manpage for more information, like calling methods with parameters.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/unmaintainable.wordpress.com/7/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/unmaintainable.wordpress.com/7/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/unmaintainable.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/unmaintainable.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/unmaintainable.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/unmaintainable.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/unmaintainable.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/unmaintainable.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/unmaintainable.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/unmaintainable.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/unmaintainable.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/unmaintainable.wordpress.com/7/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=unmaintainable.wordpress.com&blog=586265&post=7&subd=unmaintainable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://unmaintainable.wordpress.com/2006/12/19/using-dbus-introspection/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/59c9677a3b9569af44561adab6c2a980?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mafr</media:title>
		</media:content>
	</item>
	</channel>
</rss>