<?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>sixohthree.com &#187; Scripting</title>
	<atom:link href="http://sixohthree.com/category/linux/scripting/feed" rel="self" type="application/rss+xml" />
	<link>http://sixohthree.com</link>
	<description>The Weblog of Adam Backstrom</description>
	<lastBuildDate>Wed, 16 May 2012 15:01:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>mysqlhotcopy: error 24</title>
		<link>http://sixohthree.com/1698/mysqlhotcopy-error-24</link>
		<comments>http://sixohthree.com/1698/mysqlhotcopy-error-24#comments</comments>
		<pubDate>Fri, 21 Oct 2011 04:16:41 +0000</pubDate>
		<dc:creator>Adam Backstrom</dc:creator>
				<category><![CDATA[Scripting]]></category>
		<category><![CDATA[mysqlhotcopy]]></category>
		<category><![CDATA[ulimit]]></category>

		<guid isPermaLink="false">http://mu.sixohthree.com/sixohthree/?p=1698</guid>
		<description><![CDATA[What does it look like when you try to mysqlhotcopy, but don't have a high enough open files ulimit?]]></description>
			<content:encoded><![CDATA[<p>What does it look like when you try to mysqlhotcopy, but your open files ulimit is too low? If you answered &#8220;error 24 (too many open files)&#8221; you&#8217;d be correct, but also:</p>
<pre>#!/bin/sh

set -u
set -e

# non-wp tables
mysqlhotcopy --addtodest 'wordpress./^(?!wp_\d)./' /backup/

# wp tables not starting with a digit
mysqlhotcopy --addtodest 'wordpress./^wp_[^\d]/' /backup/

# tables 1-99
mysqlhotcopy --addtodest 'wordpress./^wp_\d{1,2}_/' /backup/

# tables 100-999
mysqlhotcopy --addtodest 'wordpress./^wp_\d{3}_/' /backup/

# tables 1000-1499
mysqlhotcopy --addtodest 'wordpress./^wp_1[0-4]\d{2}_/' /backup/

# tables 1500-1999
mysqlhotcopy --addtodest 'wordpress./^wp_1[5-9]\d{2}_/' /backup/

# tables 2000-2499
mysqlhotcopy --addtodest 'wordpress./^wp_2[0-4]\d{2}_/' /backup/

# tables 2500-2999
mysqlhotcopy --addtodest 'wordpress./^wp_2[5-9]\d{2}_/' /backup/
</pre>
<p>Scary.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixohthree.com/1698/mysqlhotcopy-error-24/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Makefile for CSS and JS Minify/Compress</title>
		<link>http://sixohthree.com/1380/makefile-for-css-and-js-minifycompress</link>
		<comments>http://sixohthree.com/1380/makefile-for-css-and-js-minifycompress#comments</comments>
		<pubDate>Tue, 02 Nov 2010 10:25:19 +0000</pubDate>
		<dc:creator>Adam Backstrom</dc:creator>
				<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://mu.sixohthree.com/sixohthree/?p=1380</guid>
		<description><![CDATA[I've had an ever-growing need to automate the minification and compression of CSS and JavaScript files on my web server, and while I'd written some rudimentary Makefiles in the past, I finally found time to write a kick-ass general purpose Makefile that can be applied to any project with very little modification.]]></description>
			<content:encoded><![CDATA[<p>I love <a href="http://www.gnu.org/software/make/">Makefiles</a>. Automation in all its forms is desirable, but Makefiles have a combination of surface simplicity and unknowable complexity that I find very endearing. I&#8217;ve had an ever-growing need to automate the minification and compression of CSS and JavaScript files on my web server, and while I&#8217;d written some rudimentary Makefiles in the past, I finally found time to write a kick-ass general purpose Makefile that can be applied to any project with very little modification.</p>
<p>You&#8217;ll want to have the <a href="http://developer.yahoo.com/yui/compressor/">YUI Compressor</a> and <a href="http://code.google.com/closure/compiler/">Google Closure Compiler</a> installed for minification of CSS and JavaScript, respectively. I installed them to my <code>~/bin</code> directory, and referenced that directory in my Makefile.</p>
<p>Note that I&#8217;m using these two pieces of software mostly out of habit; I haven&#8217;t evaluated them or their competitors recently.</p>
<h2>The Meat</h2>
<script src='http://gist.github.com/659427.js?file=Makefile'></script><noscript><pre>#
# css/js minification/compression makefile
#

#
#   JS_TARGETS -- js files to minify/gzip
#   CSS_TARGETS -- css files to minify/gzip
#   CLEANUP -- additional files to delete during &quot;make clean&quot;
# 

JS_TARGETS =
CSS_TARGETS =
CLEANUP =

# you can use a manifest file for targets, if that's more your style:
#CSS_TARGETS = $(shell cat manifest.txt)

# you can specify that your targets are generated by rules, and should be deleted during &quot;make clean&quot;
#CLEANUP = $(CSS_TARGETS) $(JS_TARGETS)

# google closure compiler needs every input script prefixed with --js=, as in --js=file1.js
#concatenated.min.js: file1.js file2.js
#	java -jar ~/bin/compiler.jar $(addprefix --js=,$^) &gt;$@

#custom-concat.css: file1.css file2.css file3.css
#	cat $^ &gt;$@

#######################################################
# you shouldn't need to edit anything below this line #
#######################################################

.DEFAULT_GOAL := all

all: js css

YUI = java -jar ~/bin/yuicompressor-2.4.2.jar
YUI_FLAGS = --type css

CLOSURE = java -jar ~/bin/compiler.jar
CLOSURE_FLAGS = 

.PHONY: css js

%.gz: %
	gzip -9 &lt;$&lt; &gt;$@

# css
# ---

CSS_MINIFIED = $(CSS_TARGETS:.css=.min.css)
CSS_GZIP = $(CSS_TARGETS:.css=.css.gz)
CSS_MIN_GZIP = $(CSS_TARGETS:.css=.min.css.gz)

css: $(CSS_TARGETS) $(CSS_MINIFIED) $(CSS_GZIP) $(CSS_MIN_GZIP)

%.min.css: %.css
	 $(YUI) $(YUI_FLAGS) &lt;$&lt; | sed 's/ and(/ and (/g' &gt;$@

# javascript
# ----------

JS_MINIFIED = $(JS_TARGETS:.js=.min.js)
JS_GZIP = $(JS_TARGETS:.js=.js.gz)
JS_MIN_GZIP = $(JS_TARGETS:.js=.min.js.gz)

js: $(JS_TARGETS) $(JS_MINIFIED) $(JS_GZIP) $(JS_MIN_GZIP)

%.min.js: %.js
	$(CLOSURE) $(CLOSURE_FLAGS) --js=$&lt; &gt;$@

clean:
	rm -f $(CSS_MINIFIED) $(CSS_GZIP) $(CSS_MIN_GZIP) $(JS_GZIP) $(JS_MINIFIED) $(JS_MIN_GZIP) $(CLEANUP)</pre></noscript>
<h2>Customizing for Your Project</h2>
<p>To make this file useful for your own project, you&#8217;ll need to point it at your CSS and JS files.</p>
<pre>JS_TARGETS =
CSS_TARGETS =
CLEANUP =</pre>
<p>The first two variables define what scripts will be minified and compressed when you type &#8220;make js&#8221; or &#8220;make css,&#8221; respectively. Both of these commands will run when you type &#8220;make all&#8221; or simply &#8220;make.&#8221; <code>CLEANUP</code> allows you to specify additional files that will be removed when you type &#8220;make clean.&#8221;</p>
<p>Some sample customizations are mentioned in the file.</p>
<pre>CSS_TARGETS = $(shell cat manifest.txt)</pre>
<p>If you would rather organize your list of CSS or JavaScript targets into their own files, you can automatically expand that manifest file using the cat command.</p>
<pre>CLEANUP = $(CSS_TARGETS) $(JS_TARGETS)</pre>
<p>Some more advanced setups may combine several CSS files before minification, or use a custom target to concatenate JavaScript using the closure compiler. If you find that all your targets can be cleaned, you can simply reference them automatically as above.</p>
<pre>concatenated.min.js: file1.js file2.js
	java -jar ~/bin/compiler.jar $(addprefix --js=,$^) &gt;$@</pre>
<p>The closure compiler requires a prefix for all input JavaScript files. Use the make function &#8220;<code>addprefix</code>&#8221; to format the argument list.</p>
<pre>custom-concat.css: file1.css file2.css file3.css
	cat $^ &gt;$@</pre>
<p>Automatic variables greatly simplify most of the functionality within this makefile. To create a concatenated CSS file, simplify specify the target to the left of the colon, and its dependencies (the files to concatenate) to the right; the <code>cat</code> command never needs modification.</p>
<p>Of course, you can always define custom rules, ie. this one to fetch the newest development version of jQuery:</p>
<pre>jquery:
	curl -o jquery.js http://code.jquery.com/jquery-git.js</pre>
<h2>Other Magic</h2>
<p>Some other goodness happens below the &#8220;you shouldn&#8217;t need to edit past here&#8221; line. After we configure a few settings, we define how to create files based on suffixes: .min.css gets passed through YUI Compressor, .min.js through Closure, and .gz through gzip. We configure what files we care about, and make handles the rest.</p>
<pre>.DEFAULT_GOAL := all</pre>
<p>Set a default rule, rather than using the first rule in the file as the default.</p>
<pre>.PHONY: css js</pre>
<p>Prevent files named &#8220;css&#8221; or &#8220;js&#8221; from interfering with the css and js rules.</p>
<pre>%.gz: %
	gzip -9 &lt;$&lt; &gt;$@</pre>
<p>One of three pattern rules. This enables you to compress any file (not just CSS or JS) by running &#8220;make filename.gz.&#8221; I precompress my files because I&#8217;m using <a href="http://wiki.nginx.org/NginxHttpGzipStaticModule">gzip_static in nginx</a>.</p>
<pre>CSS_GZIP = $(CSS_TARGETS:.css=.css.gz)</pre>
<p>One of several variables that modifies filenames found in <code>$(CSS_TARGETS)</code>, changing the suffix from <code>.css</code> to <code>.css.gz</code>. Note that the colon/equals syntax is shorthand for <a href="http://www.gnu.org/software/make/manual/make.html#Text-Functions">patsubst</a>. Given <code>CSS_TARGETS = text.css tables.css</code>, we would get <code>CSS_GZIP = text.css.gz tables.css.gz</code>, which would be sent as targets to the more general <code>css</code> rule, and in turn would be handled by the general-purpose <code>%.gz</code> rule above.</p>
<h2>See Also</h2>
<ul>
<li><a href="http://www.cprogramming.com/tutorial/makefiles_continued.html">Advanced Makefile Tricks</a> &#8212; macros ($@ et al) and wildcard rules</li>
<li><a href="http://www.gnu.org/software/make/manual/make.html">GNU make manual</a> &#8212; <a href="http://www.gnu.org/software/make/manual/make.html#Functions">functions</a>, <a href="http://www.gnu.org/software/make/manual/make.html#Automatic-Variables">automatic variables</a>, <a href="http://www.gnu.org/software/make/manual/make.html#Pattern-Rules">pattern rules</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://sixohthree.com/1380/makefile-for-css-and-js-minifycompress/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Bash Completion</title>
		<link>http://sixohthree.com/867/bash-completion</link>
		<comments>http://sixohthree.com/867/bash-completion#comments</comments>
		<pubDate>Fri, 05 Jun 2009 00:54:42 +0000</pubDate>
		<dc:creator>Adam Backstrom</dc:creator>
				<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Bash]]></category>
		<category><![CDATA[compgen]]></category>
		<category><![CDATA[complete]]></category>
		<category><![CDATA[productivity]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://sixohthree.com/?p=867</guid>
		<description><![CDATA[It would be difficult to <em>not</em> like bash's programmable completion. It's too bad I've had such a hard time wrapping my head around the programmable completion toolkit.]]></description>
			<content:encoded><![CDATA[<p>It would be difficult to <em>not</em> like bash&#8217;s <a href="http://www.gnu.org/software/bash/manual/bashref.html#Programmable-Completion">programmable completion</a>. Tab completion is addictive, and expanding it past files and folders into usernames, hostnames, and, well, anything you can dream up and put in a function, has incredible potential.</p>
<p>It&#8217;s too bad I&#8217;ve had such a hard time wrapping my head around the programmable completion toolkit, <code>complete</code> and <code>compgen</code>.</p>
<h3 id="867_getting-there_1">Getting There</h3>
<p>I have a function that works like <code>cd</code>, but prepends a specific directory. Our web files are stored in <code>/some/dir/webapp</code>, and I want that directory at my fingertips at all times. Here&#8217;s the function:</p>
<pre><code>wa() { cd /web/pscpages/webapp/$1 ; }</code></pre>
<p>With this function, <code>wa</code> brings me to <code>webapp</code>; <code>wa project1</code> brings me to <code>webapp/project1</code>; and so on. I just provide the full sub-path from <code>webapp</code>. Ideally, I would be able to tab-complete directories in <code>webapp</code>.</p>
<p><code>complete</code> can pull a list of possible completions from a number of sources: &#8220;actions&#8221; (like files, directories, commands, shell keywords), command output, a wordlist separated by some whitespace, or the output of a bash function, to name a few. What you&#8217;ve typed so far (the &#8220;current word&#8221;) will be used to filter all the possible completions returned by that source. Say you&#8217;ve typed &#8220;pro&#8221; and then hit tab to autocomplete. The returned completions need to match &#8220;pro&#8221; at the start of the string, meaning you can&#8217;t match against absolute paths like <code>/some/dir/webapp/project1</code>.</p>
<p><code>compgen</code> can be used to generate a list of possible completions. Matches will be output one per line, and can be piped around for transformations just like any other shell command.</p>
<p>Between these two tools, we have everything we need to autocomplete paths starting in a certain directory. Here&#8217;s a <code>compgen</code> that gives us directories matching a specified string:</p>
<pre><code>compgen -d /some/dir/webapp/</code></pre>
<p>Sample output:</p>
<pre><code>/some/dir/webapp/.svn
/some/dir/webapp/project1
/some/dir/webapp/templates
/some/dir/webapp/images</code></pre>
<p>We need to trim leading directories so &#8220;pro&#8221; matches &#8220;project1.&#8221; We should also append <code>/</code> to the pathnames, since we&#8217;re always matching directories:</p>
<pre><code>compgen -S/ -d /some/dir/webapp/ | cut -b 18-</code></pre>
<p>Playing around with <code>compgen</code>&#8216;s arguments, we can further filter the completion list by appending to our string, sort of an implied glob. Use <code>/some/dir/webapp/p</code>, and subdirectories starting with &#8220;p&#8221; will be returned. This is exactly what we want: <code>compgen</code> takes care of all the filtering for us. We have access to a couple special variables to examine the word the user is expanding. For now, it&#8217;s enough just to grab <var>${COMP_WORDS[COMP_CWORD]}</var> and append it to our path.</p>
<p>When completions are generated by a function, they&#8217;re passed back to <code>complete</code> by the <var>$COMPREPLY</var> environment variable. Pulling this all together, we can now create our completion function:</p>
<pre><code>_webapp() {
    local cur
    cur=${COMP_WORDS[COMP_CWORD]}
    COMPREPLY=( $( compgen -S/ -d /some/dir/webapp/$cur | cut -b 18- ) )
}</code></pre>
<p>All that&#8217;s left is to tell bash to use this function to complete our argument to <code>wa</code>.</p>
<pre><code>complete -o nospace -F _webapp wa</code></pre>
<h3 id="867_the-fruits_1">The Fruits</h3>
<p>So, that does it. Our original wrapper to <code>cd</code>, combined with our autocomplete functionality, looks like this:</p>
<pre><code>wa() { cd /some/dir/webapp/$1 ; }
_webapp() {
    local cur
    cur=${COMP_WORDS[COMP_CWORD]}
    COMPREPLY=( $( compgen -S/ -d /some/dir/webapp/$cur | cut -b 18- ) )
}
complete -o nospace -F _webapp wa</code></pre>
<p>Voila. Tab completion in a directory that&#8217;s not <var>$PWD</var>, and it even works with subdirectories. I hope this makes autocompletion a little clearer for others.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixohthree.com/867/bash-completion/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Google Search Options</title>
		<link>http://sixohthree.com/827/google-search-options</link>
		<comments>http://sixohthree.com/827/google-search-options#comments</comments>
		<pubDate>Wed, 13 May 2009 16:32:12 +0000</pubDate>
		<dc:creator>Adam Backstrom</dc:creator>
				<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[search]]></category>

		<guid isPermaLink="false">http://blogs.bwerp.net/?p=827</guid>
		<description><![CDATA[Google has added some search options to pages, including date-based searches, a variety of ways to find related information, and more options for displaying images with your results. Good stuff.]]></description>
			<content:encoded><![CDATA[<p><img src="///Users/adam/Desktop/search-options.png" alt="" />Google has added some search options to pages, including date-based searches, a variety of ways to find related information, and more options for displaying images with your results. Good stuff.</p>

<a href='http://sixohthree.com/827/google-search-options/search-options' title='search-options'><img width="150" height="150" src="http://sixohthree.com/files/2009/05/search-options-150x150.png" class="attachment-thumbnail" alt="search-options" title="search-options" /></a>
<a href='http://sixohthree.com/827/google-search-options/images-from-page' title='images-from-page'><img width="150" height="150" src="http://sixohthree.com/files/2009/05/images-from-page-150x150.png" class="attachment-thumbnail" alt="images-from-page" title="images-from-page" /></a>
<a href='http://sixohthree.com/827/google-search-options/timeline' title='timeline'><img width="150" height="150" src="http://sixohthree.com/files/2009/05/timeline-150x150.png" class="attachment-thumbnail" alt="timeline" title="timeline" /></a>
<a href='http://sixohthree.com/827/google-search-options/wonder-wheel' title='wonder-wheel'><img width="150" height="150" src="http://sixohthree.com/files/2009/05/wonder-wheel-150x150.png" class="attachment-thumbnail" alt="wonder-wheel" title="wonder-wheel" /></a>

]]></content:encoded>
			<wfw:commentRss>http://sixohthree.com/827/google-search-options/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Abusing screen(1)&#039;s Default Shell</title>
		<link>http://sixohthree.com/451/screen</link>
		<comments>http://sixohthree.com/451/screen#comments</comments>
		<pubDate>Fri, 25 Apr 2008 13:32:44 +0000</pubDate>
		<dc:creator>Adam Backstrom</dc:creator>
				<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Bash]]></category>
		<category><![CDATA[screen]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[Terminal]]></category>

		<guid isPermaLink="false">http://blogs.bwerp.net/?p=451</guid>
		<description><![CDATA[Three other people will find this useful.]]></description>
			<content:encoded><![CDATA[<p>Today I figured out a simple but non-obvious way of automatically connecting to a remote shell when I create new <a href="http://www.gnu.org/software/screen/">screen</a> windows. I&#8217;m using this in conjunction with a development server that does not have screen installed.</p>
<p>Let&#8217;s start at the beginning. My <code>~/.ssh/config</code> file has many entries structured like so:</p>
<pre><code>Host bob
    HostName robert.example.com
    User backstrom</code></pre>
<p>This setup allows me to SSH to robert.example.com using the shortcut <code>ssh bob</code>. This shortcut could be made even shorter, though. I have a script (say, <code>host-ssh</code>) in my $PATH with the following content:</p>
<pre><code>#!/bin/sh
HOST=$(basename $0)
ssh $HOST $@</code></pre>
<p>Now I can <code>ln -s host-ssh bob</code> to symlink host-ssh to bob, and <code>bob</code> becomes a shortcut for <code>ssh bob</code>. At this point, the following commands work as expected:</p>
<pre><code>adam@local:~$ ssh bob
backstrom@robert:~$ exit
adam@local:~$ bob
backstrom@robert:~$ exit
adam@local:~$ scp -q myfile bob:
adam@local:~$</code></pre>
<p>So, onto screen. Imagine that my workstation has screen, but my remote server &#8220;bob&#8221; does not. I can mimic the functionality by running screen locally and connecting each window to bob in its own SSH session. (In the past I have done this via <code>exec bob</code> so I have one less <code>exit</code> to type during disconnects.) However, screen allows you to set a custom shell. You can leverage this to force an SSH connection to a specific server whenever a new window is created. Just launch screen with <code>screen -s bob</code> and every ^A-c will automatically run your new SSH shortcut. Seamless, if you have public keys set up.</p>
<p><ins datetime="2008-07-10T09:22-04:00">More information is available on my <a href="http://wiki.bwerp.net/SSH">SSH wiki page</a>.</ins></p>
]]></content:encoded>
			<wfw:commentRss>http://sixohthree.com/451/screen/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Merging PDFs in Linux</title>
		<link>http://sixohthree.com/400/merge</link>
		<comments>http://sixohthree.com/400/merge#comments</comments>
		<pubDate>Thu, 12 Apr 2007 20:01:50 +0000</pubDate>
		<dc:creator>Adam Backstrom</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://blogs.bwerp.net/archives/2007/04/12/merge</guid>
		<description><![CDATA[And it all comes together.]]></description>
			<content:encoded><![CDATA[<p>There are several free utilities for merging PDFs into one document. For a long time, Ghostscript was enough for me:</p>
<pre><code>gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite \\
    -sOutputFile=collated.pdf file1.pdf file2.pdf</code></pre>
<p>Today I hit several PDFs with complex table formatting. As far as I could tell, gs (and pdf2ps) were rasterizing these documents into embedded bitmaps during processing. This dramatically increased file size and processing time. Some searching brought up <a href="http://ansuz.sooke.bc.ca/software/pdf-append.php">this page</a> and a comment suggesting the pdftk utility.</p>
<pre><code>pdftk file1.pdf file2.pdf cat output collated.pdf</code></pre>
<p>pdftk ended up producing much smaller files (far closer to what I would expect based on starting file size) at very fast speeds. And <em>watermarking</em>, oh how I searched for a utility that could watermark.</p>
<p>Thanks, <a href="http://www.accesspdf.com/pdftk/">pdftk</a> team.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixohthree.com/400/merge/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Taming Google</title>
		<link>http://sixohthree.com/328/taming</link>
		<comments>http://sixohthree.com/328/taming#comments</comments>
		<pubDate>Fri, 26 Aug 2005 17:13:09 +0000</pubDate>
		<dc:creator>Adam Backstrom</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">/?p=328</guid>
		<description><![CDATA[Down, boy.]]></description>
			<content:encoded><![CDATA[<p>You may not have noticed, but <a href="http://www.google.com/">Google</a> uses JavaScript to rewrite link URLs as you click on search results. The is presumably used for tracking and statistics and advertising number voodoo. Whatever, I don&#8217;t care. I just want it to go away.</p>
<p>If you&#8217;re running the <a href="http://greasemonkey.mozdev.org/">Greasemonkey</a> extension for <a href="http://www.mozilla.org/products/firefox/">Firefox</a>, you&#8217;re in luck. Greasemonkey allows a surfer to install custom scripts for any site, effectively letting him customize pages as he sees fit. Remove content blocks, change colors and fonts, add text, or, drumroll: remove <code>onmousedown</code> events.</p>
<p>Here&#8217;s the script:</p>
<pre><code>// By Adam Backstrom &lt;adam@sixohthree.com&gt;
// Public Domain, 8 August, 2005.
// Block Google's data mining on search results.

// find all paragraph tags
thePs = document.getElementsByTagName("P");

for(var i = 0; i 

    theP = thePs[i];
    theLinks = theP.getElementsByTagName("A"); // find anchors

    for(var j = 0; j &lt; theLinks.length; j++) {
        theLinks[j].removeAttribute(&quot;onmousedown&quot;);
    }
}</code></pre>
<p>Works well enough for me.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixohthree.com/328/taming/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Python as Calculator</title>
		<link>http://sixohthree.com/307/calculator</link>
		<comments>http://sixohthree.com/307/calculator#comments</comments>
		<pubDate>Mon, 09 May 2005 16:03:11 +0000</pubDate>
		<dc:creator>Adam Backstrom</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">/?p=307</guid>
		<description><![CDATA[Quite handy, I say.]]></description>
			<content:encoded><![CDATA[<p>As often as I need a calculator, I rarely have one within arm&#8217;s reach. I do sit in front of thousands of dollars of computer equipment nearly all day, though, and if I can&#8217;t do some arithmetic with it, well, what can I do?</p>
<p>I usually resort to <code>bc</code>, but I use it so rarely that I can never remember the correct syntax. <code>bash</code> is usually a good backup with its <code>$((1 + 1))</code> syntax that I can use right from the shell prompt, but this particular method doesn&#8217;t do floating point math. I did the find-a-suitable-calculator song and dance again today, but found a new partner this time: <a href="http://www.python.org/">Python</a>.</p>
<p>Python is a natural choice: it will return floating-point values without any additional steps, it retains a command history, and it allows for storing results in a variable. If you&#8217;re handy with printf style statements, you can even format output to your liking. As an example:</p>
<pre><code>adam@shed:~$ python
Python 2.4 (#1, Jan  1 2005, 21:33:55)
[GCC 3.3.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
&gt;&gt;&gt; 7 * 19
133
&gt;&gt;&gt; 3 / 21.0
0.14285714285714285
&gt;&gt;&gt; print "%0.2f" % (81 / 2.1)
38.57
&gt;&gt;&gt;</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://sixohthree.com/307/calculator/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Firefox Packages on Slackware</title>
		<link>http://sixohthree.com/298/pkg</link>
		<comments>http://sixohthree.com/298/pkg#comments</comments>
		<pubDate>Sun, 27 Mar 2005 17:08:58 +0000</pubDate>
		<dc:creator>Adam Backstrom</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">/?p=298</guid>
		<description><![CDATA[A time saver, for sure.]]></description>
			<content:encoded><![CDATA[<p>One of the strengths of <a href="http://www.slackware.com/">Slackware Linux</a> is the easy-to-understand packaging system. The slackware &#8220;.tgz&#8221; format is what it looks like: a compressed archive in Tar/Gzip format. It can get slightly more complicated, but that&#8217;s the foundation of all packages. The adoption of such a widely-used format allows system administrators to create working packages with very little learning curve.</p>
<p>I try to use packages when possible. Some pieces of software lend themselves to packages better than others, and <a href="http://www.mozilla.org/products/firefox/">Firefox</a> is one of those packages. Firefox is available as a .tar.gz of files (as opposed to a graphical installer). The following script (<a href="http://blogs.bwerp.net/~adam/2005/03/27/firefox-package-base/firefox.SlackBuild">download version</a>) works nicely:</p>
<pre><code>#!/bin/sh

CWD=`pwd`
PKG=/tmp/package-firefox
rm -rf $PKG

VERSION=1.0.2
ARCH=i686
BUILD=1

mkdir -p $PKG/usr/lib $PKG/usr/bin
cd $PKG/usr/lib

tar xzfv $CWD/firefox-$VERSION.tar.gz

cd $PKG/usr/bin
ln -s ../lib/firefox/firefox ./firefox

mkdir -p $PKG/usr/share/pixmaps
cp $CWD/Firefox.png $PKG/usr/share/pixmaps/Firefox.png

chown -R root:root $PKG
chown root.bin $PKG/usr/lib/firefox/firefox-bin

cd $PKG
makepkg -l y -c n ../firefox-$VERSION-$ARCH-$BUILD.tgz</code></pre>
<p>Run this as root, and in no time at all you&#8217;ll have a Slackware package that can be installed, uninstalled, and upgraded. This package requires the <a href="http://ftp.mozilla.org/pub/mozilla.org/firefox/releases/1.0.2/linux-i686/en-US/firefox-1.0.2.tar.gz">Firefox archive</a> as well as the following image file, all stored in the same directory:</p>
<p><img src="http://blogs.bwerp.net/~adam/2005/03/27/firefox-package-base/Firefox.png" height="48" width="48" alt="Firefox icon"></p>
<p>You can <a href="http://blogs.bwerp.net/~adam/2005/03/27/firefox-package-base.tar.gz">download the whole package base</a> (sans Firefox itself) if you please.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixohthree.com/298/pkg/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Bash Tips: Set Remote Variables</title>
		<link>http://sixohthree.com/282/remote</link>
		<comments>http://sixohthree.com/282/remote#comments</comments>
		<pubDate>Tue, 21 Dec 2004 02:00:30 +0000</pubDate>
		<dc:creator>Adam Backstrom</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">/?p=282</guid>
		<description><![CDATA[Seldom necessary, always difficult.]]></description>
			<content:encoded><![CDATA[<p>As I&#8217;ve mentioned, I&#8217;m now on <a href="http://www.dreamhost.com/">DreamHost</a>. It&#8217;s pretty dreamy (as you might expect), but <a href="http://www.wlug.org.nz/Screen"><code>screen</code></a> is not allowed. This is a slight inconvenience, since I rather like <code>screen</code> and use it constantly. Plan B involves running <code>screen</code> locally and SSH&#8217;ing to DreamHost in every window, but I lose my tailored bash prompt. Normally, my prompt looks like this:</p>
<pre><code>adam@aziz[0]:~$</code></pre>
<p>I can immediately tell that <code>screen</code> is running, as well as my window number. This breaks down as soon as I SSH to DreamHost. I get a far more generic prompt:</p>
<pre><code>aestus@jezebel:~$</code></pre>
<p>So, what to do? Set a variable on the remote side, in a roundabout sort of way:</p>
<pre><code>ssh -t jezebel.dreamhost.com 'export MYVAR=myvalue &amp;&amp;
      exec /bin/bash --login'</code></pre>
<p>It doesn&#8217;t look like much. It took me an hour to assemble. SSH to the host, allocating a TTY with <code>-t</code>. Run <code>bash</code> on the remote side as a login shell, executing the specified command. Export a variable, and exec a sub-bash.</p>
<p>Yeah, that&#8217;s it.</p>
<p style="border: 1px dashed red;padding: 1ex"><span style="font-weight: bold">Update 12/15/2005:</span> Trimmed the command a bit: the outer /bin/bash call is unnecessary.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixohthree.com/282/remote/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

