<?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/"
	>

<channel>
	<title>BigSmoke &#187; CLI</title>
	<atom:link href="http://blog.bigsmoke.us/tag/cli/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.bigsmoke.us</link>
	<description>Smokes your problems, coughs fresh air.</description>
	<lastBuildDate>Sat, 04 Feb 2012 18:03:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Effective CLI habits</title>
		<link>http://blog.bigsmoke.us/2010/12/24/effective-cli-habits</link>
		<comments>http://blog.bigsmoke.us/2010/12/24/effective-cli-habits#comments</comments>
		<pubDate>Thu, 23 Dec 2010 23:28:41 +0000</pubDate>
		<dc:creator>Rowan Rodrik</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[CLI]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://blog.bigsmoke.us/?p=996</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p>Just an example of some effective CLI magic that I copy/pasted into a draft <del>about</del><ins>exactly</ins> a year ago. Can you see what&#8217;s happening? I&#8217;m moving some selected files into a subdirectory.</p>

<pre>$ ls *png
boucoule-17jaar-met-steen.png         evening_cloud.png  small-map-molenweg.png  tile11.png
boucoule-2001-2002-face5-400x300.png  hardwood-logo.png  step-01.png             tile9a.png
</pre>

<pre>
$ ls *png|while read f; do echo $f; done
boucoule-17jaar-met-steen.png
boucoule-2001-2002-face5-400x300.png
evening_cloud.png
hardwood-logo.png
small-map-molenweg.png
step-01.png
tile11.png
tile9a.png
</pre>

<pre>
$ ls *png|while read f; do svn mv $f index; done
A         index/boucoule-17jaar-met-steen.png
D         boucoule-17jaar-met-steen.png
A         index/boucoule-2001-2002-face5-400x300.png
D         boucoule-2001-2002-face5-400x300.png
A         index/evening_cloud.png
D         evening_cloud.png
A         index/hardwood-logo.png
D         hardwood-logo.png
A         index/small-map-molenweg.png
D         small-map-molenweg.png
A         index/step-01.png
D         step-01.png
A         index/tile11.png
D         tile11.png
A         index/tile9a.png
D         tile9a.png
</pre>

<p>Bonus points if you notice that I could have moved the JPEGs and PNGs in one command instead of doing the same thing for the second time for the JPEGs as below. (I probably forgot that I also had some JPEGs lying around, or there must have been some other lame excuse.)</p>

<pre>
$ ls *jpg
bruggetje-225x300.jpg  favicon.jpg  purple-rowan.jpg        rowan-2007.jpg                rowan-wilderness.jpg
bruggetje.jpg          hekje.jpg    rowan-2007-448x300.jpg  rowan-wilderness-400x300.jpg
</pre>

<pre>
$ ls *jpg|grep -v favi
bruggetje-225x300.jpg
bruggetje.jpg
hekje.jpg
purple-rowan.jpg
rowan-2007-448x300.jpg
rowan-2007.jpg
rowan-wilderness-400x300.jpg
rowan-wilderness.jpg
</pre>

<pre>
$ ls *jpg|grep -v favi|while read f; do svn mv $f index; done
A         index/bruggetje-225x300.jpg
D         bruggetje-225x300.jpg
A         index/bruggetje.jpg
D         bruggetje.jpg
A         index/hekje.jpg
D         hekje.jpg
A         index/purple-rowan.jpg
D         purple-rowan.jpg
A         index/rowan-2007-448x300.jpg
D         rowan-2007-448x300.jpg
A         index/rowan-2007.jpg
D         rowan-2007.jpg
A         index/rowan-wilderness-400x300.jpg
D         rowan-wilderness-400x300.jpg
A         index/rowan-wilderness.jpg
D         rowan-wilderness.jpg
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.bigsmoke.us/2010/12/24/effective-cli-habits/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Posting to WordPress via the command-line</title>
		<link>http://blog.bigsmoke.us/2010/12/24/posting-to-wordpress-via-the-command-line</link>
		<comments>http://blog.bigsmoke.us/2010/12/24/posting-to-wordpress-via-the-command-line#comments</comments>
		<pubDate>Thu, 23 Dec 2010 23:17:16 +0000</pubDate>
		<dc:creator>Rowan Rodrik</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Atom]]></category>
		<category><![CDATA[CLI]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[XML-RPC]]></category>

		<guid isPermaLink="false">http://blog.bigsmoke.us/?p=1208</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p>In February I was interested in posting to WordPress from the command-line, a possibility that I <a href="http://blog.bigsmoke.us/2009/03/27/wikipedia-mediawiki-fuse-fs">enjoyed</a> when I wanted to apply some CLI-magic to some of my MediaWiki installations in the past.</p>

<p>I came <a href="http://leocharre.com/articles/posting-to-wordpress-via-the-command-line/">across</a> a great Perl module (<a href="http://search.cpan.org/dist/WordPress-CLI/">WordPress::CLI</a>) by Leo Charre. It depends on WordPress::XMLRPC</p>

<p>Another approach is to use the <a href="http://wanderingbarque.com/appfs/installing_appfs.html">appfs</a> FUSE filesystem, which uses WordPress&#8217; support for the Atom Publishing Protocol. There&#8217;s another FUSE filesystem, <a href="http://nixbit.com/cat/system/filesystems/blogfs/">BlogFS</a>. This one depends on WordPress&#8217; XML-RPC instead of its Atom interface.</p>

]]></content:encoded>
			<wfw:commentRss>http://blog.bigsmoke.us/2010/12/24/posting-to-wordpress-via-the-command-line/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Command line mistakes</title>
		<link>http://blog.bigsmoke.us/2010/03/13/command-line-mistakes</link>
		<comments>http://blog.bigsmoke.us/2010/03/13/command-line-mistakes#comments</comments>
		<pubDate>Sat, 13 Mar 2010 19:50:22 +0000</pubDate>
		<dc:creator>Rowan Rodrik</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[CLI]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[UNIX]]></category>

		<guid isPermaLink="false">http://blog.bigsmoke.us/2010/03/13/command-line-mistakes</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a nice post by Vivek Gite about <a href="http://www.cyberciti.biz/tips/my-10-unix-command-line-mistakes.html">ten of his biggest command line mistakes</a>. The comments are good too.</a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.bigsmoke.us/2010/03/13/command-line-mistakes/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Monitor the progress of Unix commands with Pipe Viewer (pv)</title>
		<link>http://blog.bigsmoke.us/2010/02/01/pipe-viewer</link>
		<comments>http://blog.bigsmoke.us/2010/02/01/pipe-viewer#comments</comments>
		<pubDate>Sun, 31 Jan 2010 22:23:40 +0000</pubDate>
		<dc:creator>Rowan Rodrik</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[CLI]]></category>
		<category><![CDATA[pipe-viewer]]></category>
		<category><![CDATA[pv]]></category>

		<guid isPermaLink="false">http://blog.bigsmoke.us/?p=1141</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p>I just stumbled across the <a href="http://www.catonmat.net/blog/unix-utilities-pipe-viewer/">following post</a> while trying to find out how to <a href="http://blog.bigsmoke.us/2010/01/31/xsel#vim-copy">copy text from VIM using XSel</a> without losing the selected text. It introduces Pipe Viewer, a Unix utility which is a kind of cat with a progress bar.</p>

<p>I emerged it (it&#8217;s in Gentoo (Debian too)) and it works very simple, but allows you to do cooler, more complicated things.</p>

<pre>
# pv emerge.log |gzip >emerge.log.gz
1.24MB 0:00:00 [1.76MB/s] [================>] 100%  
</pre>

<pre>
$ pv -cN source access_log | gzip | pv -cN gzip > access_log.gz
   source: 28.7MB 0:00:00 [32.2MB/s] [=====>] 100%            
     gzip: 2.27MB 0:00:00 [2.54MB/s] [ <=>  ]
</pre>

<p>The first example is easy enough to understand when you mentally substitute <tt>pv</tt> with <tt>cat</tt>. The second example is much cooler. It uses the <tt>-N</tt> flag to make named groups and the <tt>-c</tt> flag to make sure that the output for these groups doesn&#8217;t get garbled.</p>

<p>Read Peteris Krumins’ <a href="http://www.catonmat.net/blog/unix-utilities-pipe-viewer/">article</a> for more cool uses of Pipe Viewer.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.bigsmoke.us/2010/02/01/pipe-viewer/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XSel, for command-line operations on X selections</title>
		<link>http://blog.bigsmoke.us/2010/01/31/xsel</link>
		<comments>http://blog.bigsmoke.us/2010/01/31/xsel#comments</comments>
		<pubDate>Sun, 31 Jan 2010 21:44:56 +0000</pubDate>
		<dc:creator>Rowan Rodrik</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[CLI]]></category>
		<category><![CDATA[CLIPBOARD]]></category>
		<category><![CDATA[PRIMARY]]></category>
		<category><![CDATA[VIM]]></category>
		<category><![CDATA[wxcopy]]></category>
		<category><![CDATA[wxpaste]]></category>
		<category><![CDATA[X]]></category>
		<category><![CDATA[XSel]]></category>

		<guid isPermaLink="false">http://blog.bigsmoke.us/?p=1135</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p>Since I first learned that Windowmaker installs two command-line tools,
<a href="http://linux.die.net/man/1/wxcopy"><tt>wxcopy</tt></a> and <a href="http://linux.die.net/man/1/wxpaste"><tt>wxpaste</tt></a>, to play around with X selections, I have wanted to be able to make and use X selections from my Bash shell. <tt>wxcopy</tt> and <tt>wxpaste</tt> never did what I expected them to do, so I gave up until recently I learned about all the different X selections.</p>

<p>By default, <tt>wxcopy</tt> and <tt>wxpaste</tt> operate on the <tt>CUT_BUFFER[n]</tt> selections. These are deprecated. That&#8217;s why I could never make it work, because modern applications use only CLIPBOARD and SELECTION. So, <tt>wxcopy</tt> is pretty useless (unless its used to copy something to paste with wxpaste). With this knowledge <tt>wxcopy</tt> <em>does</em> seem useful thanks to its <tt>-selection [selection-name]</tt> flag, but this doesn&#8217;t seem to work; I only get the contents of CUT_BUFFER. This is not how the feature is advertised:</p>

<blockquote><dl><dt><strong><tt>-selection [selection-name]</tt></strong></dt>
<dd>The data will be copied from the named selection. If cutting from the selection fails, the cutbuffer will be used. The default value for the selection name is PRIMARY.</dd></blockquote>

<h2>Enter XSel</h2>

<p>Fortunately, there&#8217;s <a href="http://www.vergenet.net/~conrad/software/xsel/">XSel</a> by <a href="http://www.kfish.org/">Conrad Parker</a>, a program which made him passionately <a href="http://lists.slug.org.au/archives/slug-chat/2001/July/msg00054.html">hate</a> the ICCCM.</p>

<p>XSel does exactly what it advertises. I&#8217;m actually surprised that I never heard of it before. It&#8217;s available in <a href="http://packages.gentoo.org/package/x11-misc/xsel">Gentoo</a>, <a href="http://packages.debian.org/xsel">Debian</a> and <a href="http://packages.ubuntu.com/xsel">Ubuntu</a>, so it&#8217;s a breeze to install.</p>

<p>Among its features are: <strong><tt>--append</tt></strong>, <strong><tt>--follow</tt></strong>, <strong><tt>--clear</tt></strong>, <strong><tt>--delete</tt></strong> (very weird, but logical if you understand X IPC), <strong><tt>--primary</tt></strong>, <strong><tt>--secondary</tt></strong>, <strong><tt>--clipboard</tt></strong>, <strong><tt>--keep</tt></strong>, and <strong><tt>--exchange</tt></strong>. Read the man page for more. It&#8217;s an excellent read.</p>

<p>One of the places where I&#8217;m going to use this tool is when copy-pasting to and from VIM. I really like how this compares to using <tt>:insert</tt> or <tt>:r!cat</dev/tty</tt> and then using the pointer to paste (or <kbd>(Shift+)Insert</kbd> with <a href="http://blog.bigsmoke.us/2010/01/31/xterm-clipboard-selection">my custom XTerm config</a>). Now, to paste something in VIM, I can simply type:</p>

<pre>
:r!xsel
</pre>

<p id="vim-copy">I use the following to copy any amount of text from VIM. This works much better than fooling around with the mouse:</p>

<pre>
:'>,'> !tee >(xsel -i)
</pre>

<p>The <q><tt>'>,'></tt></q> range is entered automatically if you press <kbd>:</kbd> while in visual (selection) mode. You could enter any range there, or even <tt>%</tt> to select the whole file. To copy to the CLIPBOARD instead of the PRIMARY, use <q><tt>xsel -i -b</tt></q> in the above example.</p>

<p>If someone know of a way to make VIM pipe something to a program without replacing the given range with that program's output, I could simplify this…</p>

]]></content:encoded>
			<wfw:commentRss>http://blog.bigsmoke.us/2010/01/31/xsel/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Replacing the full contents of a Subversion working (sub)dir</title>
		<link>http://blog.bigsmoke.us/2010/01/14/svn-replace-dir</link>
		<comments>http://blog.bigsmoke.us/2010/01/14/svn-replace-dir#comments</comments>
		<pubDate>Wed, 13 Jan 2010 22:01:14 +0000</pubDate>
		<dc:creator>Rowan Rodrik</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[CLI]]></category>
		<category><![CDATA[diff]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[svn-replace-dir]]></category>

		<guid isPermaLink="false">http://blog.bigsmoke.us/?p=1000</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p>The annoyances that I suffered earlier today during the <a href="http://blog.bigsmoke.us/2008/03/13/upgrading-web-apps-with-diff-and-patch#comment-90523">upgrade of a WordPress plugin</a> made me turn to my <a href="http://blog.bigsmoke.us/tag/vim">favorite text-editor</a> to create a simple script, <tt><a href="http://gist.github.com/276574">svn-replace-dir</a></tt>:</p>

<pre class="bash"><span style="color: #808080; font-style: italic;">#!/bin/bash</span>
&nbsp;
usage<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
    cat &lt;&lt;<span style="color: #ff0000;">&quot;EOF&quot;</span>
$<span style="color: #cc66cc;">0</span> <span style="color: #66cc66;">&#91;</span>--dry-run<span style="color: #66cc66;">&#93;</span> &lt;svn_dir&gt; &lt;replacement_dir&gt;
&nbsp;
This script replaces the contents of &lt;svn_dir&gt; with the contents of &lt;replacement_dir&gt;,
where &lt;replacement_dir&gt; is not an svn directory.
&nbsp;
Copyleft <span style="color: #cc66cc;">2010</span>, Rowan Rodrik van der Molen &lt;rowan@bigsmoke.us&gt;
EOF
<span style="color: #66cc66;">&#125;</span>
&nbsp;
fatal_error<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
    <span style="color: #0000ff;">message=</span>$<span style="color: #cc66cc;">1</span>
&nbsp;
    <span style="color: #000066;">echo</span> -e <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\e</span>[1;31m$message<span style="color: #000099; font-weight: bold;">\e</span>[0m&quot;</span>
    <span style="color: #000066;">exit</span> <span style="color: #cc66cc;">1</span>
<span style="color: #66cc66;">&#125;</span>
&nbsp;
usage_error<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
    <span style="color: #0000ff;">error=</span><span style="color: #ff0000;">&quot;Wrong usage.&quot;</span>
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#91;</span> -n <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #66cc66;">&#93;</span>; <span style="color: #b1b100;">then</span>
        <span style="color: #0000ff;">error=</span>$<span style="color: #cc66cc;">1</span>
    <span style="color: #b1b100;">fi</span>
&nbsp;
    <span style="color: #000066;">echo</span> -e <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\e</span>[1;31m$error<span style="color: #000099; font-weight: bold;">\e</span>[0m&quot;</span>
    <span style="color: #000066;">exit</span> <span style="color: #cc66cc;">1</span>
<span style="color: #66cc66;">&#125;</span>
&nbsp;
run_command<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
    <span style="color: #000066;">echo</span> -e <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\e</span>[1;34m$1<span style="color: #000099; font-weight: bold;">\e</span>[0m&quot;</span>
&nbsp;
    <span style="color: #66cc66;">&#91;</span> <span style="color: #0000ff;">$dry_run</span> == <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">&#93;</span> || <span style="color: #000066;">eval</span> $<span style="color: #cc66cc;">1</span>
<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">dry_run=</span><span style="color: #cc66cc;">0</span>
<span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#91;</span> $<span style="color: #cc66cc;">1</span> == <span style="color: #ff0000;">'--dry-run'</span> <span style="color: #66cc66;">&#93;</span>; <span style="color: #b1b100;">then</span>
  <span style="color: #0000ff;">dry_run=</span><span style="color: #cc66cc;">1</span>
  <span style="color: #000066;">shift</span>
<span style="color: #b1b100;">fi</span>
&nbsp;
&nbsp;
<span style="color: #66cc66;">&#91;</span> $<span style="color: #808080; font-style: italic;"># == 2 ] || usage_error &quot;Wrong number of arguments.&quot;</span>
&nbsp;
<span style="color: #0000ff;">svn_dir=</span>`<span style="color: #000066;">echo</span> <span style="color: #ff0000;">&quot;$1&quot;</span>|sed -e <span style="color: #ff0000;">'s#/$##'</span>`
<span style="color: #0000ff;">replacement_dir=</span>`<span style="color: #000066;">echo</span> <span style="color: #ff0000;">&quot;$2&quot;</span>|sed -e <span style="color: #ff0000;">'s#/$##'</span>`
<span style="color: #0000ff;">begin_path=</span><span style="color: #0000ff;">$PWD</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#if [ &quot;${svn_dir:0:1}&quot; != &quot;/&quot; ]; then svn_dir=&quot;$PWD/$svn_dir&quot;; fi</span>
<span style="color: #808080; font-style: italic;">#if [ &quot;${replacement_dir:0:1}&quot; != &quot;/&quot; ]; then replacement_dir=&quot;$PWD/$replacement_dir&quot;; fi</span>
&nbsp;
<span style="color: #66cc66;">&#91;</span> -d <span style="color: #ff0000;">&quot;$svn_dir&quot;</span> <span style="color: #66cc66;">&#93;</span> || usage_error <span style="color: #ff0000;">&quot;$svn_dir is not a directory.&quot;</span>
<span style="color: #66cc66;">&#91;</span> -d <span style="color: #ff0000;">&quot;$replacement_dir&quot;</span> <span style="color: #66cc66;">&#93;</span> || usage_error <span style="color: #ff0000;">&quot;$replacement_dir is not a directory.&quot;</span>
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;"># Create all subdirectories in $svn_dir that do not yet exist</span>
<span style="color: #000066;">cd</span> <span style="color: #0000ff;">$replacement_dir</span>
find . -mindepth <span style="color: #cc66cc;">1</span> -<span style="color: #000066;">type</span> d -print | sed -e <span style="color: #ff0000;">'s#^./##'</span> | <span style="color: #b1b100;">while</span> <span style="color: #000066;">read</span> d; <span style="color: #b1b100;">do</span>
    <span style="color: #000066;">cd</span> <span style="color: #0000ff;">$begin_path</span>/<span style="color: #0000ff;">$svn_dir</span>
    <span style="color: #808080; font-style: italic;"># Doesn't the destination directory already exist?</span>
    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#91;</span> ! -d <span style="color: #ff0000;">&quot;$d&quot;</span> <span style="color: #66cc66;">&#93;</span>; <span style="color: #b1b100;">then</span>
        run_command <span style="color: #ff0000;">&quot;svn mkdir '$d'&quot;</span>
    <span style="color: #b1b100;">fi</span>
<span style="color: #b1b100;">done</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Copy all files from $replacement_dir to $svn_dir</span>
<span style="color: #000066;">cd</span> <span style="color: #0000ff;">$begin_path</span>/<span style="color: #0000ff;">$replacement_dir</span>
find . -<span style="color: #000066;">type</span> f -print | sed -e <span style="color: #ff0000;">'s#^./##'</span> | <span style="color: #b1b100;">while</span> <span style="color: #000066;">read</span> f; <span style="color: #b1b100;">do</span>
    <span style="color: #000066;">cd</span> <span style="color: #0000ff;">$begin_path</span>
    run_command <span style="color: #ff0000;">&quot;cp '$replacement_dir/$f' '$svn_dir/$f'&quot;</span> <span style="color: #808080; font-style: italic;"># FIXME: Quoting problem</span>
<span style="color: #b1b100;">done</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Remove all files that do no longer exist in $replacement dir</span>
<span style="color: #000066;">cd</span> <span style="color: #0000ff;">$begin_path</span>/<span style="color: #0000ff;">$svn_dir</span>
find . -<span style="color: #000066;">type</span> f -print | grep -v <span style="color: #ff0000;">'.svn'</span> | <span style="color: #b1b100;">while</span> <span style="color: #000066;">read</span> f; <span style="color: #b1b100;">do</span>
    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#91;</span> ! -f <span style="color: #ff0000;">&quot;$begin_path/$replacement_dir/$f&quot;</span> <span style="color: #66cc66;">&#93;</span>; <span style="color: #b1b100;">then</span>
        run_command <span style="color: #ff0000;">&quot;svn rm '$f'&quot;</span>
    <span style="color: #b1b100;">fi</span>
<span style="color: #b1b100;">done</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Remove all subdirs that do no longer exist in $replacement dir</span>
<span style="color: #000066;">cd</span> <span style="color: #0000ff;">$begin_path</span>/<span style="color: #0000ff;">$svn_dir</span>
find . -mindepth <span style="color: #cc66cc;">1</span> -<span style="color: #000066;">type</span> d -print | grep -v <span style="color: #ff0000;">'.svn'</span> | <span style="color: #b1b100;">while</span> <span style="color: #000066;">read</span> d; <span style="color: #b1b100;">do</span>
    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#91;</span> ! -d <span style="color: #ff0000;">&quot;$begin_path/$replacement_dir/$d&quot;</span> <span style="color: #66cc66;">&#93;</span>; <span style="color: #b1b100;">then</span>
        run_command <span style="color: #ff0000;">&quot;svn rm '$d'&quot;</span>
    <span style="color: #b1b100;">fi</span>
<span style="color: #b1b100;">done</span>
&nbsp;
<span style="color: #000066;">exit</span> <span style="color: #cc66cc;">0</span></pre>

<p>Using the script is simple:</p>

<pre class="bash">svn-replace-dir simple-tags new-simple-tags|less -R</pre>

<p>It replaces all the contents of the first directory (<q><tt>simple-tags</tt></q> in the example) with those of the second directory and it deletes everything that is no longer present in the second dir. In the process, it does all the necessary calls to <tt>svn mkdir</tt>, <tt>svn rm</tt> and (in the next version) <tt>svn add</tt>.</p>

<p><tt>diff</tt> tells me that the script has done its work correctly:</p>

<pre class="bash">diff -x .svn -ruN simple-tags new-simple-tags
<span style="color: #808080; font-style: italic;"># Emptiness is bliss :-) </span></pre>

<p>This is another one of these occasions when Git would have made life so much easier. Luckily, at least there&#8217;s GitHub to host this script as a Gist. <a href="http://gist.github.com/276574">Check there</a> if you want to fetch the newest version of this script.</p> ]]></content:encoded>
			<wfw:commentRss>http://blog.bigsmoke.us/2010/01/14/svn-replace-dir/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dumping a bunch of MP3s as WAV files</title>
		<link>http://blog.bigsmoke.us/2009/12/06/mp3-to-wav</link>
		<comments>http://blog.bigsmoke.us/2009/12/06/mp3-to-wav#comments</comments>
		<pubDate>Sun, 06 Dec 2009 20:17:26 +0000</pubDate>
		<dc:creator>Rowan Rodrik</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[CLI]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MP3]]></category>
		<category><![CDATA[mpg123]]></category>
		<category><![CDATA[WAV]]></category>

		<guid isPermaLink="false">http://blog.bigsmoke.us/?p=891</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p>I just used the following command for converting a directory with a bunch of MP3s to WAV. Does someone know a command that is shorter? I find mine a bit convoluted to say the least.</p>

<pre class="bash">mkdir wav
ls *mp3|while <span style="color: #000066;">read</span> i; <span style="color: #b1b100;">do</span>  mpg123 --stdout <span style="color: #ff0000;">&quot;$i&quot;</span> &gt; wav/`<span style="color: #000066;">echo</span> <span style="color: #0000ff;">$i</span>|sed -r -e <span style="color: #ff0000;">'s/^([0-9]+) .*$/<span style="color: #000099; font-weight: bold;">\1</span>/'</span>`.wav; <span style="color: #b1b100;">done</span></pre>

<p>The directory looks like this:</p>

<pre>
$ ls -1
01 - Meant to Be.mp3
02 - Reflections.mp3
03 - Semester Days.mp3
04 - Friend.mp3
05 - True Gemini.mp3
06 - Down the Road.mp3
07 - Tulip Trees.mp3
08 - Not Alone.mp3
09 - Woods of Chaos.mp3
10 - Twilight.mp3
[en] Readme - www.jamendo.com .txt
[es] Lee me - www.jamendo.com .txt
[fr] Lisez moi - www.jamendo.com .txt
[it] Readme - www.jamendo.com .txt
License.txt
Rob Costlow - Solo Piano - Woods of Chaos.1.0.jpg
</pre>]]></content:encoded>
			<wfw:commentRss>http://blog.bigsmoke.us/2009/12/06/mp3-to-wav/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tracking WordPress in a Subversion vendor branch</title>
		<link>http://blog.bigsmoke.us/2009/09/20/svn-vendor-branches-wordpress</link>
		<comments>http://blog.bigsmoke.us/2009/09/20/svn-vendor-branches-wordpress#comments</comments>
		<pubDate>Sun, 20 Sep 2009 11:03:34 +0000</pubDate>
		<dc:creator>Rowan Rodrik</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[CLI]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://blog.bigsmoke.us/?p=824</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p>Two months prior to writing a <a href="http://blog.bigsmoke.us/2009/07/20/svn-vendor-branches">script to upgrade MediaWiki installations using Subversion vendor branches</a>, I wrote something similar for WordPress. It&#8217;s a little bit more limited and should really incorporate some of the improvements made for the MediaWiki version, but it worked fine so far:</p>

<pre class="bash">cat upgrade-wordpress.sh 
<span style="color: #808080; font-style: italic;">#!/bin/bash</span>
&nbsp;
<span style="color: #0000ff;">svn_repo_url=</span>file:///var/svn/blog.omega-research.org/vendor/wordpress/
<span style="color: #0000ff;">last_version=</span>$<span style="color: #cc66cc;">1</span>
<span style="color: #0000ff;">new_version=</span>$<span style="color: #cc66cc;">2</span>
&nbsp;
<span style="color: #0000ff;">tmp_dir=</span>`mktemp -d`
<span style="color: #000066;">cd</span> <span style="color: #0000ff;">$tmp_dir</span>
&nbsp;
<span style="color: #b1b100;">for</span> version <span style="color: #b1b100;">in</span> $*; <span style="color: #b1b100;">do</span>
    <span style="color: #000066;">echo</span> <span style="color: #ff0000;">&quot;Downloading and extracting WordPress version $version...&quot;</span>
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#91;</span> -z `svn ls <span style="color: #0000ff;">$svn_repo_url</span>|grep <span style="color: #0000ff;">$version</span>` <span style="color: #66cc66;">&#93;</span>; <span style="color: #b1b100;">then</span>
        <span style="color: #0000ff;">branch=</span>`<span style="color: #000066;">echo</span> <span style="color: #0000ff;">$version</span> |sed -e <span style="color: #ff0000;">'s/<span style="color: #000099; font-weight: bold;">\.</span>[0-9]<span style="color: #000099; font-weight: bold;">\+</span>$//'</span>`
        <span style="color: #0000ff;">archive_file=</span><span style="color: #ff0000;">&quot;wordpress-$version.tar.gz&quot;</span>
        <span style="color: #0000ff;">md5_file=</span><span style="color: #ff0000;">&quot;wordpress-$version.md5&quot;</span>
&nbsp;
        wget <span style="color: #ff0000;">&quot;http://wordpress.org/$md5_file&quot;</span>
        wget <span style="color: #ff0000;">&quot;http://wordpress.org/$archive_file&quot;</span>
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#91;</span> `md5sum <span style="color: #0000ff;">$archive_file</span> |cut -f <span style="color: #cc66cc;">1</span> -d <span style="color: #ff0000;">' '</span>` != `cat <span style="color: #0000ff;">$md5_file</span>` <span style="color: #66cc66;">&#93;</span>; <span style="color: #b1b100;">then</span>
            <span style="color: #000066;">echo</span> <span style="color: #ff0000;">&quot;MD5 sum did not match!&quot;</span> &gt;&amp;<span style="color: #cc66cc;">2</span>
            <span style="color: #000066;">exit</span> <span style="color: #cc66cc;">1</span>
        <span style="color: #b1b100;">fi</span>
&nbsp;
        tar --extract --ungzip --transform <span style="color: #ff0000;">&quot;s/^wordpress/$version/&quot;</span> --file <span style="color: #0000ff;">$archive_file</span>
        svn_load_dirs.pl <span style="color: #0000ff;">$svn_repo_url</span> -t <span style="color: #0000ff;">$version</span> current <span style="color: #0000ff;">$version</span>
    <span style="color: #b1b100;">fi</span>
<span style="color: #b1b100;">done</span>
&nbsp;
<span style="color: #000066;">cd</span> -
svn merge <span style="color: #ff0000;">&quot;$svn_repo_url$last_version&quot;</span> <span style="color: #ff0000;">&quot;$svn_repo_url$new_version&quot;</span> .</pre>

<p>I&#8217;m actually planning to make both scripts a little bit more generic (in the sense that <tt>svn_repo_url</tt> becomes an external param) and to track future changes to them using GitHub&#8217;s <a href="http://gist.github.com/">Gist</a>. (How ironic is that, tracking an script for Subversion using Git?)</p>]]></content:encoded>
			<wfw:commentRss>http://blog.bigsmoke.us/2009/09/20/svn-vendor-branches-wordpress/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Tracking MediaWiki in a Subversion vendor branch</title>
		<link>http://blog.bigsmoke.us/2009/07/20/svn-vendor-branches</link>
		<comments>http://blog.bigsmoke.us/2009/07/20/svn-vendor-branches#comments</comments>
		<pubDate>Mon, 20 Jul 2009 12:33:44 +0000</pubDate>
		<dc:creator>Rowan Rodrik</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[CLI]]></category>
		<category><![CDATA[MediaWiki]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[svn]]></category>

		<guid isPermaLink="false">http://blog.bigsmoke.us/?p=672</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p>Vendor branches are the proper™ way of merging upstream changes in your web application installations. In Subversion, <a href="http://svnbook.red-bean.com/en/1.4/svn.advanced.vendorbr.html">managing vendor branches</a> isn&#8217;t so easy as it is in Git. Still, vendor branches make it much easier to track upstream.</p> 

<p>From before I first deployed the <a href="http://wiki.omega-research.org/Main_Page">Omega Research Wiki</a>, I already used svn to track changes to my MediaWiki installation. However, for upgrading from one upstream release to the next, I <a href="http://blog.bigsmoke.us/2008/03/13/upgrading-web-apps-with-diff-and-patch">used diff and patch</a>. This isn&#8217;t the most reliable of methods as is exemplified by doing a diff comparing a fresh MediaWiki download with the actual files in my repo (which are supposed to belong to the same version).</p>

<p>What&#8217;s basically a shortcoming of svn is that I can&#8217;t just say:</p>

<pre class="bash">svn merge http://svn.wikimedia.org/svnroot/mediawiki/tags/REL1_15_0/phase3/ \
http://svn.wikimedia.org/svnroot/mediawiki/tags/REL1_15_1/phase3/ .</pre>

<p>This would have been incredibly helpful, because now I&#8217;m keeping a vendor branch not because of local modifications to upstream, but just to be able to merge cleanly.</p>

<p>In Subversion, maintaining a vendor branch by hand is quite some work, because you need to do a checkout first before you can import each version. (My working copy is normally a checkout of <tt>/trunk</tt>, not of <tt>/vendor/mediawiki</tt>.) Luckily, Subversion is distributed with a handy Perl script, <tt>svn_load_dirs.pl</tt>, which can do most of the heavy lifting.</p>

<p>Still, I didn&#8217;t feel like having to do to many manual steps, such as typing in the painfully long URLs for merging, so I decided to wrap the whole process into a nice little Bash script:</p>

<pre class="bash">cat upgrade-mediawiki.sh
<span style="color: #808080; font-style: italic;">#!/bin/bash</span>
&nbsp;
<span style="color: #0000ff;">svn_repo_url=</span>file:///var/svn/wiki.omega-research.org/vendor/mediawiki/
&nbsp;
<span style="color: #0000ff;">merge=</span><span style="color: #cc66cc;">1</span>
<span style="color: #b1b100;">while</span> <span style="color: #66cc66;">&#91;</span> $<span style="color: #808080; font-style: italic;"># -gt 2 ] # Process extra options</span>
<span style="color: #b1b100;">do</span>
    <span style="color: #b1b100;">case</span> <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #b1b100;">in</span>
        --no-merge<span style="color: #66cc66;">&#41;</span>
            <span style="color: #0000ff;">merge=</span><span style="color: #cc66cc;">0</span>
            ;;
    <span style="color: #b1b100;">esac</span>
    <span style="color: #000066;">shift</span>
<span style="color: #b1b100;">done</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#91;</span> $<span style="color: #808080; font-style: italic;"># -ne 2 ]; then</span>
    <span style="color: #000066;">echo</span> <span style="color: #ff0000;">&quot;Usage: $0 [--no-merge] version version&quot;</span>
    <span style="color: #000066;">exit</span> <span style="color: #cc66cc;">1</span>
<span style="color: #b1b100;">fi</span>
&nbsp;
<span style="color: #0000ff;">last_version=</span>$<span style="color: #cc66cc;">1</span>
<span style="color: #0000ff;">new_version=</span>$<span style="color: #cc66cc;">2</span>
&nbsp;
<span style="color: #0000ff;">tmp_dir=</span>`mktemp -d`
<span style="color: #000066;">cd</span> <span style="color: #0000ff;">$tmp_dir</span>
&nbsp;
<span style="color: #b1b100;">for</span> version <span style="color: #b1b100;">in</span> $*; <span style="color: #b1b100;">do</span>
    <span style="color: #000066;">echo</span> <span style="color: #ff0000;">&quot;Downloading and extracting MediaWiki version $version...&quot;</span>
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#91;</span> -z `svn ls <span style="color: #0000ff;">$svn_repo_url</span>|grep <span style="color: #0000ff;">$version</span>` <span style="color: #66cc66;">&#93;</span>; <span style="color: #b1b100;">then</span>
        <span style="color: #0000ff;">branch=</span>`<span style="color: #000066;">echo</span> <span style="color: #0000ff;">$version</span> |sed -e <span style="color: #ff0000;">'s/<span style="color: #000099; font-weight: bold;">\.</span>[0-9]<span style="color: #000099; font-weight: bold;">\+</span>$//'</span>`
        <span style="color: #0000ff;">download_file=</span><span style="color: #ff0000;">&quot;mediawiki-$version.tar.gz&quot;</span>
        <span style="color: #0000ff;">download_url=</span><span style="color: #ff0000;">&quot;http://download.wikimedia.org/mediawiki/$branch/$download_file&quot;</span>
&nbsp;
        wget <span style="color: #0000ff;">$download_url</span> || <span style="color: #66cc66;">&#123;</span> <span style="color: #000066;">echo</span> <span style="color: #ff0000;">&quot;Downloading $download_file failed&quot;</span>&gt;&amp;<span style="color: #cc66cc;">2</span>; <span style="color: #000066;">exit</span> <span style="color: #cc66cc;">1</span>; <span style="color: #66cc66;">&#125;</span>
        tar --extract --ungzip --transform <span style="color: #ff0000;">'s/^mediawiki-//'</span> --file <span style="color: #0000ff;">$download_file</span>
        svn_load_dirs.pl <span style="color: #0000ff;">$svn_repo_url</span> -t <span style="color: #0000ff;">$version</span> current <span style="color: #0000ff;">$version</span>
    <span style="color: #b1b100;">fi</span>
<span style="color: #b1b100;">done</span>
&nbsp;
<span style="color: #000066;">cd</span> -
<span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#91;</span> <span style="color: #0000ff;">$merge</span> == <span style="color: #ff0000;">'1'</span> <span style="color: #66cc66;">&#93;</span>; <span style="color: #b1b100;">then</span>
    svn merge <span style="color: #ff0000;">&quot;$svn_repo_url$last_version&quot;</span> <span style="color: #ff0000;">&quot;$svn_repo_url$new_version&quot;</span> .
<span style="color: #b1b100;">fi</span>
&nbsp;
<span style="color: #000066;">exit</span> <span style="color: #cc66cc;">0</span></pre>

<p>The script only downloads and imports each specified version if that version doesn&#8217;t already exist in <tt>/vendor/mediawiki/</tt>. Also, because it has a <tt>--no-merge</tt> option, you can download all the old versions of MediaWiki that you&#8217;ve ever used, so that you can go back and compare old versions of your installation with the factory version. Of course, this is only useful if you were already tracking your installation in svn at the time, and even then not really. <img src='http://blog.bigsmoke.us/wp-factory/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>

<p>Anyway, the important thing is that you can use the script to download the version you&#8217;re running now and the version you want to upgrade too. I wanted to make a big jump, from 1.11.1 to 1.15.0 (I had put of the upgrade for a long time, because I first wanted to learn more about vendor branches):</p>

<p>Of course, as always, you need to check if the patch went well. My own results were a vivid demonstration of the unreliability of my previous method:</p>

<pre class="bash">svn st|grep <span style="color: #ff0000;">'^C'</span></pre>

<pre>
C      languages/messages/MessagesKrj.php
C      languages/messages/MessagesWar.php
C      languages/messages/MessagesSe.php
C      languages/messages/MessagesFrc.php
</pre>

<p>Luckily, these were all files I was sure I hadn&#8217;t modified:</p>

<pre class="bash"><span style="color: #b1b100;">for</span> i <span style="color: #b1b100;">in</span> `svn st|grep <span style="color: #ff0000;">'^C'</span>|sed -e <span style="color: #ff0000;">'s/^C //'</span>`; <span style="color: #b1b100;">do</span> mv <span style="color: #0000ff;">$i</span>.merge-right.r32 <span style="color: #0000ff;">$i</span>; svn resolved <span style="color: #0000ff;">$i</span>; <span style="color: #b1b100;">done</span></pre>

<pre>
Resolved conflicted state of 'languages/messages/MessagesKrj.php'
Resolved conflicted state of 'languages/messages/MessagesWar.php'
Resolved conflicted state of 'languages/messages/MessagesSe.php'
Resolved conflicted state of 'languages/messages/MessagesFrc.php'
</pre>

<p>Apparently, a previous upgrade hadn&#8217;t turned my MediaWiki installation <em>exactly</em> into 1.11.1.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.bigsmoke.us/2009/07/20/svn-vendor-branches/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>winepath</title>
		<link>http://blog.bigsmoke.us/2009/06/28/winepath</link>
		<comments>http://blog.bigsmoke.us/2009/06/28/winepath#comments</comments>
		<pubDate>Sun, 28 Jun 2009 15:38:53 +0000</pubDate>
		<dc:creator>Rowan Rodrik</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[CLI]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Wine]]></category>
		<category><![CDATA[winepath]]></category>

		<guid isPermaLink="false">http://blog.bigsmoke.us/?p=660</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p>I have all these little scripts in my <tt>$HOME/bin</tt> directory to ease the execution of Windows programs. For instance, I don&#8217;t like to type the full path to Excel Viewer every time when I need to view an Excel sheet in Linux:</p>

<pre class="bash"><span style="color: #808080; font-style: italic;">#!/bin/sh</span>
<span style="color: #ff0000;">&quot;/home/bigsmoke/.wine/drive_c/Program Files/Microsoft Office/OFFICE11/XLVIEW.EXE&quot;</span> <span style="color: #ff0000;">&quot;$*&quot;</span></pre>

<p>This works pretty well, except when trying to view a document that&#8217;s not in the current directory:</p>

<pre class="bash">xlview <span style="color: #ff0000;">&quot;/tmp/Some Excel sheet sent to me by someone.xls&quot;</span></pre>

<p>To make that work, you need to use a handy utility that comes with <a href="http://www.winehq.org/">Wine</a>, <a href="http://wiki.winehq.org/winepath">winepath</a>. With winepath, I can modify the script to work (the example is for wordview):</p>

<pre class="bash"><span style="color: #808080; font-style: italic;">#!/bin/bash</span>
<span style="color: #0000ff;">path=</span>`winepath --windows <span style="color: #ff0000;">&quot;$*&quot;</span>`
<span style="color: #ff0000;">&quot;/home/bigsmoke/.wine/drive_c/Program Files/Microsoft Office/OFFICE11/WORDVIEW.EXE&quot;</span> <span style="color: #ff0000;">&quot;$path&quot;</span></pre>

<p>This, together with Linux&#8217;s <a href="http://blog.bigsmoke.us/2009/06/28/native-execution-of-windows-programs-on-linux">binfmt_misc</a> makes executing Windows programs on Linux a breeze.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.bigsmoke.us/2009/06/28/winepath/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

