<?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>Erics Tech Blog</title>
	<atom:link href="http://eric.lubow.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://eric.lubow.org</link>
	<description>Thoughts, musings, and other idealistic (sometimes useful) systems and development hoopla.</description>
	<lastBuildDate>Mon, 16 Aug 2010 12:30:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Counting Frequencies of Frequencies</title>
		<link>http://eric.lubow.org/2010/tips/counting-frequencies-of-frequencies/</link>
		<comments>http://eric.lubow.org/2010/tips/counting-frequencies-of-frequencies/#comments</comments>
		<pubDate>Mon, 16 Aug 2010 12:30:13 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[awk]]></category>
		<category><![CDATA[bash]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=775</guid>
		<description><![CDATA[Lots of people forget about the usefulness of the core utilities (the tools available in Bash). I am even pretty guilty of it at times with such quick and easy things like Perl, Ruby, or Python that allow you to process items from the command line. However, they load up an entire interpreter. It is [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Feric.lubow.org%2F2010%2Ftips%2Fcounting-frequencies-of-frequencies%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Feric.lubow.org%2F2010%2Ftips%2Fcounting-frequencies-of-frequencies%2F&amp;source=elubow&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>Lots of people forget about the usefulness of the core utilities (the tools available in Bash).  I am even pretty guilty of it at times with such quick and easy things like Perl, Ruby, or Python that allow you to process items from the command line.  However, they load up an entire interpreter.  It is usually better to use the coreutils.<br />
<span id="more-775"></span></p>
<p>I&#8217;ll give you the specific example I had to deal with, but this can be extrapolated out and I&#8217;m sure reused for other purposes.  I have lists of email addresses of who has received emails that were sent over the past 7 days.  I do this with a find command since the address files are created nightly.  They are laid out with 1 email address (and some other meta data) per line.  You&#8217;ll notice the <strong>awk</strong> in the find command; that&#8217;s just to extract the email address from the line to make things easier to work with.</p>
<p>The overall goal here is find out how many times people were emailed over the past 7 days.  Another way of saying it is, how many people received 1,2,3,4, etc mailings over the past week.  This is an exercise in aggregation.</p>
<p>First, here is everything in its entirety and then I will proceed to go through it all piece by piece.</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ <span style="color: #c20cb9; font-weight: bold;">find</span> <span style="color: #000000; font-weight: bold;">/</span>nfs<span style="color: #000000; font-weight: bold;">/</span>mailings<span style="color: #000000; font-weight: bold;">/</span>lists<span style="color: #000000; font-weight: bold;">/</span> <span style="color: #660033;">-maxdepth</span> <span style="color: #000000;">3</span> <span style="color: #660033;">-ctime</span> <span style="color: #660033;">-7</span> <span style="color: #660033;">-name</span> <span style="color: #ff0000;">&quot;master_list.txt&quot;</span> \<br />
<span style="color: #660033;">-exec</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $2}'</span> <span style="color: #ff0000;">'{}'</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #000000; font-weight: bold;">/</span>emails.txt \; <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #000000; font-weight: bold;">/</span>emails.txt <span style="color: #000000; font-weight: bold;">|</span> \<br />
<span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{ for (i=1;i&lt; =NF;i++) count[$i]++ } &nbsp;END { for (i in count) print count[i], i }'</span> <span style="color: #007800;">$*</span> <span style="color: #000000; font-weight: bold;">|</span>\<br />
<span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $1}'</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{ for (i=1;i&lt;=NF;i++) count[$i]++ } &nbsp;\<br />
END { for (i in count) print count[i], i }'</span> <span style="color: #007800;">$*</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $2,$1}'</span> <span style="color: #000000; font-weight: bold;">|</span> \<br />
<span style="color: #c20cb9; font-weight: bold;">sort</span> <span style="color: #660033;">-n</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-rf</span> <span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #000000; font-weight: bold;">/</span>emails.txt<br />
<span style="color: #000000;">1</span> <span style="color: #000000;">93278</span><br />
<span style="color: #000000;">2</span> <span style="color: #000000;">21415</span><br />
<span style="color: #000000;">3</span> <span style="color: #000000;">16924</span><br />
<span style="color: #000000;">4</span> <span style="color: #000000;">3064131</span><br />
<span style="color: #000000;">5</span> <span style="color: #000000;">548421</span><br />
<span style="color: #000000;">6</span> <span style="color: #000000;">102</span></div></div>
<p>A quick breakdown goes as follows.</p>
<p>1) Find all mailing list master files (-name) that aren&#8217;t archived (-maxdepth) that were created in the last 7 days (-ctime) and print their id (exec awk) to a tmp file. Everything here needs to be concatenated so as not to clobber the emails added by the previous day.<br />
</code></p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #c20cb9; font-weight: bold;">find</span> <span style="color: #000000; font-weight: bold;">/</span>nfs<span style="color: #000000; font-weight: bold;">/</span>mailings<span style="color: #000000; font-weight: bold;">/</span>lists<span style="color: #000000; font-weight: bold;">/</span> <span style="color: #660033;">-maxdepth</span> <span style="color: #000000;">3</span> <span style="color: #660033;">-ctime</span> <span style="color: #660033;">-7</span> <span style="color: #660033;">-name</span> <span style="color: #ff0000;">&quot;master_list.txt&quot;</span>\<br />
<span style="color: #660033;">-exec</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $2}'</span> <span style="color: #ff0000;">'{}'</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #000000; font-weight: bold;">/</span>emails.txt \;</div></div>
<p>2) The next piece word frequency counts the emails and prints them to STDOUT in a <cnt> <email> manner. This is to say that the first column is a count of how many times the second column has received an email over the past 7 days.  Now we know how many emails each individual has received and we need to aggregate again.</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #000000; font-weight: bold;">/</span>emails.txt <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{ for (i=1;i&lt; =NF;i++) count[$i]++ } &nbsp;\<br />
END { for (i in count) print count[i], i }'</span> <span style="color: #007800;">$*</span></div></div>
<p>3) Because I am using pipes, instead of printing the previous step to STDOUT, I only print the first column (count) and then count the frequency of that.<br />
</code></p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $1} | awk '</span><span style="color: #7a0874; font-weight: bold;">&#123;</span> <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #007800;">i</span>=<span style="color: #000000;">1</span>;i<span style="color: #000000; font-weight: bold;">&lt;</span> =NF;i++<span style="color: #7a0874; font-weight: bold;">&#41;</span> count<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #007800;">$i</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>++ <span style="color: #7a0874; font-weight: bold;">&#125;</span> \<br />
END <span style="color: #7a0874; font-weight: bold;">&#123;</span> <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>i <span style="color: #000000; font-weight: bold;">in</span> count<span style="color: #7a0874; font-weight: bold;">&#41;</span> print count<span style="color: #7a0874; font-weight: bold;">&#91;</span>i<span style="color: #7a0874; font-weight: bold;">&#93;</span>, i <span style="color: #7a0874; font-weight: bold;">&#125;</span><span style="color: #ff0000;">' $*</span></div></div>
<p>4) Then I swap the columns so I get <freq>
<person_count>.  This is much more logical and is the way we generally read tables.</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $2,$1}'</span></div></div>
<p>5) Finally I sort that result numerically ascending and remove the temp file so I don't cat things to it again.</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #c20cb9; font-weight: bold;">sort</span> <span style="color: #660033;">-n</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-rf</span> <span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #000000; font-weight: bold;">/</span>emails.txt</div></div>
<p>6) We get our output in an easy to read format (Note: I added the headers).</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Freq &nbsp; Total<br />
&nbsp;<span style="color: #000000;">1</span> &nbsp; &nbsp; <span style="color: #000000;">93278</span><br />
&nbsp;<span style="color: #000000;">2</span> &nbsp; &nbsp; <span style="color: #000000;">21415</span><br />
&nbsp;<span style="color: #000000;">3</span> &nbsp; &nbsp; <span style="color: #000000;">16924</span><br />
&nbsp;<span style="color: #000000;">4</span> &nbsp; &nbsp; <span style="color: #000000;">3064131</span><br />
&nbsp;<span style="color: #000000;">5</span> &nbsp; &nbsp; <span style="color: #000000;">548421</span><br />
&nbsp;<span style="color: #000000;">6</span> &nbsp; &nbsp; <span style="color: #000000;">102</span></div></div>
</person_count></freq></code></email></cnt></p>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2009/databases/mysql/counting-email-addresses-by-domain-in-mysql/' rel='bookmark' title='Permanent Link: Counting Email Addresses By Domain in MySQL'>Counting Email Addresses By Domain in MySQL</a></li>
<li><a href='http://eric.lubow.org/2007/perl/emailfind/' rel='bookmark' title='Permanent Link: Email::Find'>Email::Find</a></li>
<li><a href='http://eric.lubow.org/2010/mac/count-instead-of-sequence/' rel='bookmark' title='Permanent Link: Count Instead of Sequence'>Count Instead of Sequence</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2010/tips/counting-frequencies-of-frequencies/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting a Random Record From a MongoDB Collection</title>
		<link>http://eric.lubow.org/2010/databases/mongodb/getting-a-random-record-from-a-mongodb-collection/</link>
		<comments>http://eric.lubow.org/2010/databases/mongodb/getting-a-random-record-from-a-mongodb-collection/#comments</comments>
		<pubDate>Mon, 09 Aug 2010 11:15:10 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=767</guid>
		<description><![CDATA[One of my issues with MongoDB is that, as of this writing, there is no way to retrieve a random record. In SQL, you can simply do something similar to &#8220;ORDER BY RAND()&#8221; (this varies depending on your flavor) and you can retrieve random records (at a slightly expensive query cost). There is not yet [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Feric.lubow.org%2F2010%2Fdatabases%2Fmongodb%2Fgetting-a-random-record-from-a-mongodb-collection%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Feric.lubow.org%2F2010%2Fdatabases%2Fmongodb%2Fgetting-a-random-record-from-a-mongodb-collection%2F&amp;source=elubow&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>One of my issues with <a href="http://www.mongodb.org/">MongoDB</a> is that, as of this writing, there is no way to retrieve a random record.  In SQL, you can simply do something similar to &#8220;ORDER BY RAND()&#8221; (this varies depending on your flavor) and you can retrieve random records (at a slightly expensive query cost).  There is not yet an equivalent in MongoDB because of its sequential access nature.  There is a purely Javascript method in the MongoDB cookbook <a href="http://cookbook.mongodb.org/patterns/random-attribute/">here</a>.  If you are really interested, I would also read the Jira ticket thread <a href="http://jira.mongodb.org/browse/SERVER-533">#533</a> on this issue.<br />
<span id="more-767"></span><br />
Although it feels a little dirty and kind of hackish, here is how I accomplished getting a random record using the <a href="http://github.com/mongodb/mongo-ruby-driver">Mongo-Ruby driver</a>.  Part of this is documented in the cookbook article I linked to above, but I reiterate bits and pieces of it here.  This is essentially the same thing that any &#8220;ORDER BY RAND()&#8221; statement is doing, its just not doing it &#8220;on the fly&#8221;.</p>
<p>The first thing you&#8217;ll have to do is add an additional column to the collection; we&#8217;ll call it <em>random</em>.  For the ease of use, we&#8217;ll also say that every value that goes in this column is between 0 and 1 (and can therefore be generated via <em>Kernel.rand()</em>).  This is important because we are going to use it as our criteria for finding a random record.</p>
<p>First, initialized the connection to the database and bind an instance variable to a collection.  Then generate the random number that you are going to use to find a random record.  Now we try to <strong>find_one</strong> document that is greater than or equal to our random number.  In case we miss, we also do a less than or equal to next.  This means that as long as we have at least 1 document in our collection, we will return a record.  The more documents in the collection, the better the randomness of the returned document.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">@@mongodb = <span style="color:#6666ff; font-weight:bold;">Mongo::Connection</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;localhost&quot;</span>, <span style="color:#006666;">27017</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">db</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;test_db}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#0066ff; font-weight:bold;">@collection</span> = @@mongodb<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;collection_name&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span><br />
<br />
@<span style="color:#CC0066; font-weight:bold;">rand</span> = <span style="color:#CC00FF; font-weight:bold;">Kernel</span>.<span style="color:#CC0066; font-weight:bold;">rand</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#0066ff; font-weight:bold;">@random_record</span> = <span style="color:#0066ff; font-weight:bold;">@collection</span>.<span style="color:#9900CC;">find_one</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">'random'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">'$gte'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> @<span style="color:#CC0066; font-weight:bold;">rand</span> <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@random_record</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>?<br />
&nbsp; <span style="color:#0066ff; font-weight:bold;">@random_record</span> = <span style="color:#0066ff; font-weight:bold;">@collection</span>.<span style="color:#9900CC;">find_one</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">'random'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">'$lte'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> @<span style="color:#CC0066; font-weight:bold;">rand</span> <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>For reference, a mongodb collection with a random column may look like this:</p>
<div class="codecolorer-container javascript default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #3366CC;">&quot;_id&quot;</span> <span style="color: #339933;">:</span> ObjectId<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;4c5c710e41b89d657d000001&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #3366CC;">&quot;url&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;http://www.example.com/&quot;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #3366CC;">&quot;created_at&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Fri Aug 06 2010 16:32:15 GMT-0400 (EDT)&quot;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #3366CC;">&quot;random&quot;</span> <span style="color: #339933;">:</span> <span style="color: #CC0000;">0.45929463868260356</span><br />
<span style="color: #009900;">&#125;</span></div></div>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2010/databases/mongodb/getting-a-random-record-from-a-mongodb-collection/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Sharing a Screen Session</title>
		<link>http://eric.lubow.org/2010/system-administration/sharing-a-screen-session/</link>
		<comments>http://eric.lubow.org/2010/system-administration/sharing-a-screen-session/#comments</comments>
		<pubDate>Fri, 23 Jul 2010 12:47:23 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[System Administration]]></category>
		<category><![CDATA[system]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=762</guid>
		<description><![CDATA[Anyone who has spent any time in a shell and has been cut off while working should know about screen. If not, then I recommend reading up on it (here or here). But I&#8217;m not here to tell you about screen as a general tool, I want to show you how to use it for [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Feric.lubow.org%2F2010%2Fsystem-administration%2Fsharing-a-screen-session%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Feric.lubow.org%2F2010%2Fsystem-administration%2Fsharing-a-screen-session%2F&amp;source=elubow&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>Anyone who has spent any time in a shell and has been cut off while working should know about screen.  If not, then I recommend reading up on it (<a href="http://www.rackaid.com/resources/linux-screen-tutorial-and-how-to/">here</a> or <a href="http://www.linuxforums.org/articles/the-screen-program_55.html">here</a>).  But I&#8217;m not here to tell you about screen as a general tool, I want to show you how to use it for screen sharing.  I found a couple of forum posts and other scattered information, so here&#8217;s a little centralizing of information.<br />
<span id="more-762"></span><br />
First a definition, sharing a screen session means both users can at the very least view the same screen (console) at the same time.  And depending on the security settings, they can both type as well (which can be very annoying depending on who your sharing the screen session with).  I&#8217;m going to assume you know the basics so we&#8217;ll go on from there.</p>
<p>Let&#8217;s assume that I <strong>elubow</strong> want to share my console with <strong>jdoe</strong>.  After screen is installed, these next 2 steps are critical otherwise the sessions will not be accessible to other users regardless of which commands you issue inside of the screen session:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">chmod</span> +s <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">screen</span> &nbsp;<span style="color: #666666; font-style: italic;"># Make screen suid root</span><br />
$ <span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">chmod</span> <span style="color: #000000;">755</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>run<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">screen</span> <span style="color: #666666; font-style: italic;"># Make the screen dir more open</span></div></div>
<p>The easiest way to do this next part is to actually name your screen session.  So let&#8217;s call our session <strong>test</strong>.</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ <span style="color: #c20cb9; font-weight: bold;">screen</span> <span style="color: #660033;">-S</span> <span style="color: #7a0874; font-weight: bold;">test</span></div></div>
<p>This will create the session and put you in it.  Now we need to add the access control.  Note: You can automate the <em>multiuser</em> piece by adding it to you <strong>.screenrc</strong>.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">CTRL-A<br />
:multiuser on<br />
<br />
CTRL-A<br />
:acladd jdoe</div></div>
<p>All <em>jdoe</em> has to do now is connect to the same machine and type the following command:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ <span style="color: #c20cb9; font-weight: bold;">screen</span> <span style="color: #660033;">-x</span> elubow<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">test</span> &nbsp; <span style="color: #666666; font-style: italic;"># $user/$session_name</span></div></div>
<p>There are other security combinations as the above gives <strong>jdoe</strong> full access.  Here are a few common ones:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">:aclchg user +rx &nbsp;# Give 'user' read-only access<br />
:aclchg user -x &quot;#,at,aclchg,acladd,acldel,quit&quot; &nbsp;# Don't allow 'user' any of the previous commands<br />
:aclchg user +rwx &nbsp;# Give 'user' read-write access (open permission on the session)</div></div>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2010/system-administration/cluster-ssh-with-csshx/' rel='bookmark' title='Permanent Link: Cluster SSH with cSSHx'>Cluster SSH with cSSHx</a></li>
<li><a href='http://eric.lubow.org/2007/linux-security/10-tips-to-start-securing-your-linux-system/' rel='bookmark' title='Permanent Link: 10 Tips To Start Securing Your Linux System'>10 Tips To Start Securing Your Linux System</a></li>
<li><a href='http://eric.lubow.org/2007/linux-security/ssh-organization-tips/' rel='bookmark' title='Permanent Link: SSH Organization Tips'>SSH Organization Tips</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2010/system-administration/sharing-a-screen-session/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stopping Curb From Segfaulting</title>
		<link>http://eric.lubow.org/2010/ruby/stopping-curb-from-segfaulting/</link>
		<comments>http://eric.lubow.org/2010/ruby/stopping-curb-from-segfaulting/#comments</comments>
		<pubDate>Thu, 08 Jul 2010 11:30:00 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[homebrew]]></category>
		<category><![CDATA[rubygems]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=759</guid>
		<description><![CDATA[While trying to get the curb gem up and running using Ruby 1.8.7p174, I kept getting segmentation faults. I Google&#8217;d around and really wasn&#8217;t able to come up with much other than lots of people saying not to use ports here. Since I don&#8217;t use Mac Ports, I use Homebrew, I figured this wasn&#8217;t an [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Feric.lubow.org%2F2010%2Fruby%2Fstopping-curb-from-segfaulting%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Feric.lubow.org%2F2010%2Fruby%2Fstopping-curb-from-segfaulting%2F&amp;source=elubow&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>While trying to get the <a href="http://curb.rubyforge.org/">curb</a> gem up and running using Ruby 1.8.7p174, I kept getting segmentation faults.  I Google&#8217;d around and really wasn&#8217;t able to come up with much other than lots of people saying not to use ports here.  Since I don&#8217;t use <a href="http://www.macports.org/">Mac Ports</a>, I use <a href="http://github.com/mxcl/homebrew">Homebrew</a>, I figured this wasn&#8217;t an issue.  I had also recently installed the latest XCode so I incorrectly assumed there was no issue there either.  (Note: I am running on a freshly upgraded version of Mac OS X Snow Leopard).<br />
<span id="more-759"></span><br />
Since everything built correctly, I just assumed it would work correctly.  Here it is obviously not doing so.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ruby<span style="color:#006600; font-weight:bold;">-</span>1.8.7<span style="color:#006600; font-weight:bold;">-</span>p174 <span style="color:#006600; font-weight:bold;">&gt;</span> &nbsp; <span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'curb'</span><br />
<span style="color:#006600; font-weight:bold;">/</span>Users<span style="color:#006600; font-weight:bold;">/</span>elubow<span style="color:#006600; font-weight:bold;">/</span>.<span style="color:#9900CC;">rvm</span><span style="color:#006600; font-weight:bold;">/</span>gems<span style="color:#006600; font-weight:bold;">/</span>ruby<span style="color:#006600; font-weight:bold;">-</span>1.8.7<span style="color:#006600; font-weight:bold;">-</span>p174<span style="color:#006600; font-weight:bold;">/</span>gems<span style="color:#006600; font-weight:bold;">/</span>curb<span style="color:#006600; font-weight:bold;">-</span>0.7.7.1<span style="color:#006600; font-weight:bold;">/</span>lib<span style="color:#006600; font-weight:bold;">/</span>curb_core.<span style="color:#9900CC;">bundle</span>: <span style="color:#006600; font-weight:bold;">&#91;</span>BUG<span style="color:#006600; font-weight:bold;">&#93;</span> Segmentation fault<br />
ruby 1.8.7 <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">2009</span><span style="color:#006600; font-weight:bold;">-</span>06<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">12</span> patchlevel <span style="color:#006666;">174</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#91;</span>i686<span style="color:#006600; font-weight:bold;">-</span>darwin10.4.0<span style="color:#006600; font-weight:bold;">&#93;</span><br />
Abort <span style="color:#CC0066; font-weight:bold;">trap</span></div></div>
<p>So I narrowed it down to what I believe is an issue with the curl headers.  The solution is to install a new curl library.  Since I wanted to do it the Homebrew way, and Homebrew doesn&#8217;t have curl by default, here is what I did.</p>
<p>Copy the Homebrew Formula code from <a href="http://github.com/adamv/homebrew/blob/duplicates/Library/Formula/curl.rb">http://github.com/adamv/homebrew/blob/duplicates/Library/Formula/curl.rb</a> into a file named <strong>curl.rb</strong> in your formula directory (mine is <em>/usr/local/Library/Formula/</em>). You should then be able to:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">elubow<span style="color: #000000; font-weight: bold;">@</span>beacon tmp$ brew <span style="color: #c20cb9; font-weight: bold;">install</span> curl<br />
==<span style="color: #000000; font-weight: bold;">&gt;</span> Downloading http:<span style="color: #000000; font-weight: bold;">//</span>curl.haxx.se<span style="color: #000000; font-weight: bold;">/</span>download<span style="color: #000000; font-weight: bold;">/</span>curl-7.21.0.tar.bz2<br />
<span style="color: #666666; font-style: italic;">######################################################################## 100.0%</span><br />
==<span style="color: #000000; font-weight: bold;">&gt;</span> .<span style="color: #000000; font-weight: bold;">/</span>configure <span style="color: #660033;">--prefix</span>=<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>Cellar<span style="color: #000000; font-weight: bold;">/</span>curl<span style="color: #000000; font-weight: bold;">/</span>7.21.0 <span style="color: #660033;">--disable-debug</span> <span style="color: #660033;">--disable-dependency-track</span><br />
==<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #c20cb9; font-weight: bold;">install</span><br />
<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>Cellar<span style="color: #000000; font-weight: bold;">/</span>curl<span style="color: #000000; font-weight: bold;">/</span>7.21.0: <span style="color: #000000;">72</span> files, 1.8M, built <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000;">3.6</span> minutes</div></div>
<p>Don&#8217;t forget to logout and log back into the shell so the new version of curl is available:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ curl <span style="color: #660033;">--version</span><br />
curl 7.21.0 <span style="color: #7a0874; font-weight: bold;">&#40;</span>x86_64-apple-darwin10.4.0<span style="color: #7a0874; font-weight: bold;">&#41;</span> libcurl<span style="color: #000000; font-weight: bold;">/</span>7.21.0 OpenSSL<span style="color: #000000; font-weight: bold;">/</span>0.9.8l zlib<span style="color: #000000; font-weight: bold;">/</span>1.2.3 libssh2<span style="color: #000000; font-weight: bold;">/</span>1.2.2<br />
Protocols: dict <span style="color: #c20cb9; font-weight: bold;">file</span> <span style="color: #c20cb9; font-weight: bold;">ftp</span> ftps http https imap imaps ldap ldaps pop3 pop3s rtsp <span style="color: #c20cb9; font-weight: bold;">scp</span> sftp smtp smtps telnet tftp <br />
Features: IPv6 Largefile NTLM SSL libz</div></div>
<p>Now you have to uninstall and reinstall the curb gem.  The easiest way that I found (since I have bundler installed) was to do <strong>bundle show curb</strong> to find out where the gem is located.  I removed the directory and reran <strong>bundle install</strong> (or <strong>gem install curb</strong> if you don&#8217;t have bundler).</p>
<p>Because I am using <a href="http://rvm.beginrescueend.com/">rvm (Ruby Version Manager)</a>, I actually encountered this issue with 1.9.1p378 as well.  This fixed the issue for both versions.</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2010/ruby/stopping-curb-from-segfaulting/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Creating Configuration Files With Ruby Templates</title>
		<link>http://eric.lubow.org/2010/system-administration/creating-configuration-files-with-ruby-templates/</link>
		<comments>http://eric.lubow.org/2010/system-administration/creating-configuration-files-with-ruby-templates/#comments</comments>
		<pubDate>Wed, 30 Jun 2010 11:45:58 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[System Administration]]></category>
		<category><![CDATA[system]]></category>
		<category><![CDATA[tricks]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=749</guid>
		<description><![CDATA[I recently had a very repetitive configuration file that needed creating. There were approximately 50 config blocks of 10 lines each with only the host name changing with each block. So I decided to take a shortcut and do it in Ruby using ERB templates. This is so easy and literally save me hours worth [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Feric.lubow.org%2F2010%2Fsystem-administration%2Fcreating-configuration-files-with-ruby-templates%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Feric.lubow.org%2F2010%2Fsystem-administration%2Fcreating-configuration-files-with-ruby-templates%2F&amp;source=elubow&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>I recently had a very repetitive configuration file that needed creating.  There were approximately 50 config blocks of 10 lines each with only the host name changing with each block.  So I decided to take a shortcut and do it in Ruby using ERB templates. This is so easy and literally save me hours worth of work.<br />
<span id="more-749"></span><br />
I started out by creating a template for the <a href="http://www.rsyslog.com/">rsyslog</a> block I wanted to replicate.  In the full version of the script, there is an additional section for the access.log file which you&#8217;ll see below.  If you know Rails, then this template style should look very familiar.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">rsyslog_block = <span style="color:#006600; font-weight:bold;">%</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#008000; font-style:italic;">#</span><br />
<span style="color:#008000; font-style:italic;"># &lt; %= virtual_host %&gt;</span><br />
<span style="color:#008000; font-style:italic;">#</span><br />
<span style="color:#ff6633; font-weight:bold;">$InputFileName</span> <span style="color:#006600; font-weight:bold;">/</span>var<span style="color:#006600; font-weight:bold;">/</span>log<span style="color:#006600; font-weight:bold;">/</span>httpd<span style="color:#006600; font-weight:bold;">/&lt;</span> <span style="color:#006600; font-weight:bold;">%</span>= virtual_host <span style="color:#006600; font-weight:bold;">%&gt;-</span>error.<span style="color:#9900CC;">log</span><br />
<span style="color:#ff6633; font-weight:bold;">$InputFileTag</span> <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#006600; font-weight:bold;">%</span>= virtual_host <span style="color:#006600; font-weight:bold;">%&gt;</span>_error<br />
<span style="color:#ff6633; font-weight:bold;">$InputFileStateFile</span> stat<span style="color:#006600; font-weight:bold;">-&lt;</span> <span style="color:#006600; font-weight:bold;">%</span>= virtual_host <span style="color:#006600; font-weight:bold;">%&gt;-</span>error.<span style="color:#9900CC;">log</span><br />
<span style="color:#ff6633; font-weight:bold;">$InputFileSeverity</span> info<br />
<span style="color:#ff6633; font-weight:bold;">$InputFileFacility</span> local5<br />
<span style="color:#ff6633; font-weight:bold;">$InputRunFileMonitor</span><br />
<br />
<span style="color:#006600; font-weight:bold;">&#125;</span></div></div>
<p>The below block of code creates a configuration block (above) for each of virtual hosts in the array and then prints it to the screen.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#006600; font-weight:bold;">%</span>w<span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; vhost.<span style="color:#9900CC;">com</span><br />
&nbsp; &nbsp; bar.<span style="color:#9900CC;">myhost</span>.<span style="color:#9900CC;">com</span><br />
<span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>virtual_host<span style="color:#006600; font-weight:bold;">|</span> &nbsp;<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#CC00FF; font-weight:bold;">ERB</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span> rsyslog_block <span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">result</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC0066; font-weight:bold;">binding</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span></div></div>
<p>This is going to produce the following block which you can then pipe to a file:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">...Removed for brevity...<br />
#<br />
# bar.myhost.com<br />
#<br />
$InputFileName /var/log/httpd/bar.myhost.com-error.log<br />
$InputFileTag bar.myhost.com_error<br />
$InputFileStateFile stat-bar.myhost.com-error.log<br />
$InputFileSeverity info<br />
$InputFileFacility local5<br />
$InputRunFileMonitor</div></div>
<p>Here is the script in its entirety:<br />
<script src="http://gist.github.com/456080.js"></script></p>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2009/ruby/parsing-ini-files-with-ruby/' rel='bookmark' title='Permanent Link: Parsing Ini Files With Ruby'>Parsing Ini Files With Ruby</a></li>
<li><a href='http://eric.lubow.org/2010/ruby/multiple-input-locations-from-bash-into-ruby/' rel='bookmark' title='Permanent Link: Multiple Input Locations From Bash Into Ruby'>Multiple Input Locations From Bash Into Ruby</a></li>
<li><a href='http://eric.lubow.org/2010/system-administration/creating-dummy-packages-on-debian/' rel='bookmark' title='Permanent Link: Creating Dummy Packages On Debian'>Creating Dummy Packages On Debian</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2010/system-administration/creating-configuration-files-with-ruby-templates/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Random Tech Notes And Buzz Updates</title>
		<link>http://eric.lubow.org/2010/tips/random-tech-notes-and-buzz-updates/</link>
		<comments>http://eric.lubow.org/2010/tips/random-tech-notes-and-buzz-updates/#comments</comments>
		<pubDate>Mon, 28 Jun 2010 12:00:00 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[buzz]]></category>
		<category><![CDATA[google]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=746</guid>
		<description><![CDATA[Since Google Buzz is Twitterish in the sense that you can post a quick note, but different in the sense that (amongst other things), it can be longer than 140 characters. So in that vein, I&#8217;m starting to try to make a habit of a quick post (a couple per week) of things I do [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Feric.lubow.org%2F2010%2Ftips%2Frandom-tech-notes-and-buzz-updates%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Feric.lubow.org%2F2010%2Ftips%2Frandom-tech-notes-and-buzz-updates%2F&amp;source=elubow&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>Since <a href="http://www.google.com/buzz">Google Buzz</a> is <a href="http://twitter.com/">Twitter</a>ish in the sense that you can post a quick note, but different in the sense that (amongst other things), it can be longer than 140 characters.  So in that vein, I&#8217;m starting to try to make a habit of a quick post (a couple per week) of things I do to make my life easier.  This goes both for SysAdmins and for Programmers.<br />
<span id="more-746"></span><br />
I&#8217;ll be adding things for everything from Vim and Bash, to MySQL, Perl, Ruby, Python, and any other language or app that I happen to be using shortcuts in.  If you have another idea or a better way to do something, I&#8217;d love to hear it. So add a comment or hit me up on Twitter (<a href="http://twitter.com/elubow">@elubow</a>). I&#8217;ve already got a few up there so check them out.</p>
<p>And for the record, I am not trying to mimic or one up something like <a href="http://www.commandlinefu.com/">commandlinefu.com</a>.  Just providing things that work well in my world. </p>
<p>The Google Buzz account is <a href="http://www.google.com/buzz/eric.lubow/">here</a>.</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2010/tips/random-tech-notes-and-buzz-updates/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Unique Keys and Key Groups with Background Jobs in Gearman::Client</title>
		<link>http://eric.lubow.org/2010/perl/perl-modules/using-unique-keys-and-key-groups-with-background-jobs-in-gearmanclient/</link>
		<comments>http://eric.lubow.org/2010/perl/perl-modules/using-unique-keys-and-key-groups-with-background-jobs-in-gearmanclient/#comments</comments>
		<pubDate>Wed, 16 Jun 2010 12:15:35 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Perl Modules]]></category>
		<category><![CDATA[drizzle]]></category>
		<category><![CDATA[gearman]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=739</guid>
		<description><![CDATA[While diving into Gearman using Gearman::Client with MySQL and libdrizzle (I know, a mouthful), I ran into what I thought was a bug. I was only able to add 1 background job of any type at a particular time. The launchpad &#8220;bug note,&#8221; which is available in its entirety here, is rightly labeled won&#8217;t fix. [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Feric.lubow.org%2F2010%2Fperl%2Fperl-modules%2Fusing-unique-keys-and-key-groups-with-background-jobs-in-gearmanclient%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Feric.lubow.org%2F2010%2Fperl%2Fperl-modules%2Fusing-unique-keys-and-key-groups-with-background-jobs-in-gearmanclient%2F&amp;source=elubow&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>While diving into <a href="http://www.gearman.org/">Gearman</a> using <a href="http://search.cpan.org/~dormando/Gearman-1.11/lib/Gearman/Client.pm">Gearman::Client</a> with <a href="http://www.mysql.com/">MySQL</a> and <a href="http://www.drizzle.org/">libdrizzle</a> (I know, a mouthful), I ran into what I thought was a bug.  I was only able to add 1 background job of any type at a particular time.  The launchpad &#8220;bug note,&#8221; which is available in its entirety <a href="https://bugs.launchpad.net/gearmand/+bug/480775">here</a>, is rightly labeled <strong>won&#8217;t fix</strong>.<br />
<span id="more-739"></span><br />
Tracking that post down wasn&#8217;t too difficult, but it would have saved me time if that information was in the Perl documentation.  Using Gearman::Client you can create your unique ID (or UUID).  To create a background job, your code would then look like this:</p>
<div class="codecolorer-container perl default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">use</span> Gearman<span style="color: #339933;">::</span><span style="color: #006600;">Client</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">use</span> UUID<span style="color: #339933;">::</span><span style="color: #006600;">Tiny</span> <span style="color: #ff0000;">':std'</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$client</span> <span style="color: #339933;">=</span> Gearman<span style="color: #339933;">::</span><span style="color: #006600;">Client</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #339933;">;</span><br />
<span style="color: #0000ff;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">dispatch_background</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;send_email&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$json</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#123;</span> &nbsp; <br />
&nbsp; &nbsp; &nbsp;on_complete <span style="color: #339933;">=&gt;</span> <span style="color: #000000; font-weight: bold;">sub</span> <span style="color: #009900;">&#123;</span> <a href="http://perldoc.perl.org/functions/print.html"><span style="color: #000066;">print</span></a> <span style="color: #0000ff;">$</span><span style="color: #009900;">&#123;</span> <span style="color: #0000ff;">$_</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp;uniq <span style="color: #339933;">=&gt;</span> create_uuid_as_string<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span> &nbsp; <br />
&nbsp;<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>This will ensure that you have a unique UUID when INSERTing the job.  But I think that we can do better and this is where the good practice comes into effect (and why the Gearman devs marked it as won&#8217;t fix).  So let&#8217;s think a little more abstractly for a moment. For the <strong>uniq</strong> key (<strong>unique_key</strong> column), how about something like <em>&#8220;${type}_&#8221;.create_uuid_as_string()</em>. This will allow us to group (in this case) our mailing types so that we can monitor the status of our work queue.  Yes, we can easily hop into the database and run this query:</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">mysql<span style="color: #66cc66;">&gt;</span> <span style="color: #993333; font-weight: bold;">SELECT</span> function_name<span style="color: #66cc66;">,</span>COUNT<span style="color: #66cc66;">&#40;</span>function_name<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> gearman_queue <span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> function_name;<br />
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">---------------+----------------------+</span><br />
<span style="color: #66cc66;">|</span> function_name <span style="color: #66cc66;">|</span> COUNT<span style="color: #66cc66;">&#40;</span>function_name<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">|</span><br />
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">---------------+----------------------+</span><br />
<span style="color: #66cc66;">|</span> send_email &nbsp; &nbsp;<span style="color: #66cc66;">|</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #cc66cc;">3</span> <span style="color: #66cc66;">|</span> <br />
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">---------------+----------------------+</span></div></div>
<p>But wouldn&#8217;t it be nicer to know exactly where we are at with this query:</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">mysql<span style="color: #66cc66;">&gt;</span> <span style="color: #993333; font-weight: bold;">SELECT</span> IFNULL<span style="color: #66cc66;">&#40;</span>function_name<span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Total'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #993333; font-weight: bold;">FUNCTION</span><span style="color: #66cc66;">,</span> SUBSTRING_INDEX<span style="color: #66cc66;">&#40;</span>unique_key<span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'_'</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> mail_type<span style="color: #66cc66;">,</span> COUNT<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">*</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> Total<br />
<span style="color: #993333; font-weight: bold;">FROM</span> gearman_queue<br />
<span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> function_name<span style="color: #66cc66;">,</span> mail_type<br />
<span style="color: #993333; font-weight: bold;">WITH</span> ROLLUP;<br />
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">------------+-----------+-------+</span><br />
<span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">FUNCTION</span> &nbsp; <span style="color: #66cc66;">|</span> mail_type <span style="color: #66cc66;">|</span> Total <span style="color: #66cc66;">|</span><br />
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">------------+-----------+-------+</span><br />
<span style="color: #66cc66;">|</span> send_email <span style="color: #66cc66;">|</span> passreset <span style="color: #66cc66;">|</span> &nbsp; &nbsp; <span style="color: #cc66cc;">2</span> <span style="color: #66cc66;">|</span> <br />
<span style="color: #66cc66;">|</span> send_email <span style="color: #66cc66;">|</span> regemail &nbsp;<span style="color: #66cc66;">|</span> &nbsp; &nbsp; <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">|</span> <br />
<span style="color: #66cc66;">|</span> send_email <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">NULL</span> &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">|</span> &nbsp; &nbsp; <span style="color: #cc66cc;">3</span> <span style="color: #66cc66;">|</span> <br />
<span style="color: #66cc66;">|</span> Total &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">NULL</span> &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">|</span> &nbsp; &nbsp; <span style="color: #cc66cc;">3</span> <span style="color: #66cc66;">|</span> <br />
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">------------+-----------+-------+</span></div></div>
<p>For reference, here are the <em>unique_key</em> columns that allowed to generate that query:</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">mysql<span style="color: #66cc66;">&gt;</span> <span style="color: #993333; font-weight: bold;">SELECT</span> unique_key <span style="color: #993333; font-weight: bold;">FROM</span> gearman_queue;<br />
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">------------------------------------------------+</span><br />
<span style="color: #66cc66;">|</span> unique_key &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">|</span><br />
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">------------------------------------------------+</span><br />
<span style="color: #66cc66;">|</span> passreset_1cdb347b<span style="color: #66cc66;">-</span>788f<span style="color: #66cc66;">-</span>11df<span style="color: #66cc66;">-</span>ad7d<span style="color: #66cc66;">-</span>b190002f5dcd <span style="color: #66cc66;">|</span> <br />
<span style="color: #66cc66;">|</span> passreset_21ed3ae5<span style="color: #66cc66;">-</span>788f<span style="color: #66cc66;">-</span>11df<span style="color: #66cc66;">-</span><span style="color: #cc66cc;">8395</span><span style="color: #66cc66;">-</span>aed7743cedde <span style="color: #66cc66;">|</span> <br />
<span style="color: #66cc66;">|</span> regemail_2a40bebe<span style="color: #66cc66;">-</span>788f<span style="color: #66cc66;">-</span>11df<span style="color: #66cc66;">-</span>bda0<span style="color: #66cc66;">-</span>8fb882f63de5 &nbsp;<span style="color: #66cc66;">|</span> <br />
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">------------------------------------------------+</span></div></div>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2008/databases/mysql/mysql-encoded-uri-search-and-replace/' rel='bookmark' title='Permanent Link: MySQL Encoded URI Search and Replace'>MySQL Encoded URI Search and Replace</a></li>
<li><a href='http://eric.lubow.org/2009/system-administration/howto-recreate-devnull/' rel='bookmark' title='Permanent Link: HOWTO Recreate /dev/null'>HOWTO Recreate /dev/null</a></li>
<li><a href='http://eric.lubow.org/2010/databases/mysql/speeding-up-your-selects-and-sorts/' rel='bookmark' title='Permanent Link: Speeding Up Your Selects and Sorts'>Speeding Up Your Selects and Sorts</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2010/perl/perl-modules/using-unique-keys-and-key-groups-with-background-jobs-in-gearmanclient/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My First Drobo Experience</title>
		<link>http://eric.lubow.org/2010/backup/my-first-drobo-experience/</link>
		<comments>http://eric.lubow.org/2010/backup/my-first-drobo-experience/#comments</comments>
		<pubDate>Wed, 02 Jun 2010 12:00:33 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[backup]]></category>
		<category><![CDATA[drobo]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=736</guid>
		<description><![CDATA[The Drobo is supposed to be one of those solutions that essentially pops out of the box and with very little effort, just works. I ordered my Drobo FS through an Amazon retailer. What I wasn&#8217;t expecting was an experience&#8230; The whole &#8220;Drobo Experience&#8221; starts out when you open up the box it&#8217;s shipped in. [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Feric.lubow.org%2F2010%2Fbackup%2Fmy-first-drobo-experience%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Feric.lubow.org%2F2010%2Fbackup%2Fmy-first-drobo-experience%2F&amp;source=elubow&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>The <a href="http://www.drobo.com/">Drobo</a> is supposed to be one of those solutions that essentially pops out of the box and with very little effort, just works. I ordered my <a href="http://www.drobo.com/products/drobo-fs.php">Drobo FS</a> through an <a href="http://www.amazon.com/">Amazon</a> retailer.  What I wasn&#8217;t expecting was an experience&#8230;<br />
<span id="more-736"></span><br />
The whole &#8220;Drobo Experience&#8221; starts out when you open up the box it&#8217;s shipped in. The first thing you see is a box that reads, &#8220;Welcome to the World of&#8230;&#8221; What a great way to start.  This would make <a href="http://sethgodin.typepad.com/">Seth Godin</a> proud.  The actual unit was wrapped in a black cloth that said Drobo.  In fact, when you remove the top box that says, &#8220;welcome to the world of&#8221;, you see a black box that says Drobo. That&#8217;s just cool.  The front even has a magnetic cover (very weak magnets in order to not affect the drives) in the front to provide a clean look.</p>
<p>Now on to the actual product.  This could not have been easier to get going.  I had myself all geared for a few hours of work.  Instead, I just threw the drives in, powered them on and was in business.  And the fact that the Drobo now <a href="http://www.drobo.com/news/pr/press_release_2010_05_20a.php">natively supports Time Machine</a> made it all that much easier.  One thing I did do is download a <a href="http://www.drobo.com/droboapps/downloads/index.php?id=16">Drobo app</a> that limits the size of a Time Machine Partition.  This ensures that Time machine doesn&#8217;t eat up your entire Drobo partition (which Time Machine can do quickly if left unattended).</p>
<p>Now that the important stuff is out of the way and I have the Drobo setup with Time Machine, I moved onto setting up DroboApps.  Again, this could not have been any simpler.  Just mount the DroboApps share and copy the <em>.tgz</em> files to it and restart the Drobo.  Boom! Done deal.</p>
<p>This has seriously been one of the most pleasurable hardware experiences I have had in a long time.  I wish someone at Data Robotics was paying or something for this glowing recommendation, but no such luck.  This is just one of those products that gets its right.  Remember the cliche, &#8220;you get what you pay for?&#8221;  Well this is a perfect example.</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2010/backup/my-first-drobo-experience/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Multiple Input Locations From Bash Into Ruby</title>
		<link>http://eric.lubow.org/2010/ruby/multiple-input-locations-from-bash-into-ruby/</link>
		<comments>http://eric.lubow.org/2010/ruby/multiple-input-locations-from-bash-into-ruby/#comments</comments>
		<pubDate>Thu, 13 May 2010 12:00:59 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[bash]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=723</guid>
		<description><![CDATA[I have been trying to figure out how, while using OptionParser to be able to check for files being input on the command line and if they don&#8217;t exist, check other input streams (like Bash). This initially wasn&#8217;t very easy since input streams are blocking. So with a little help from friends (thanks roberto), I [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Feric.lubow.org%2F2010%2Fruby%2Fmultiple-input-locations-from-bash-into-ruby%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Feric.lubow.org%2F2010%2Fruby%2Fmultiple-input-locations-from-bash-into-ruby%2F&amp;source=elubow&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>I have been trying to figure out how, while using <a href="http://ruby-doc.org/stdlib/libdoc/optparse/rdoc/classes/OptionParser.html">OptionParser</a> to be able to check for files being input on the command line and if they don&#8217;t exist, check other input streams (like Bash).  This initially wasn&#8217;t very easy since input streams are blocking.  So with a little help from friends (thanks roberto), I was able to use his method of non-blocking IO and wrap it in a begin/rescue block.  I also took a little advice given in this <a href="http://www.stackoverflow.com">Stack Overflow</a> question called <a href="http://stackoverflow.com/questions/273262/best-practices-with-stdin-in-ruby">Best Practices with STDIN in Ruby.</a><br />
<span id="more-723"></span><br />
First we need to get the file list off the command line and assume that anything left are files.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#0066ff; font-weight:bold;">@opts</span> = OptionParser.<span style="color:#9900CC;">new</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>o<span style="color:#006600; font-weight:bold;">|</span><br />
...<br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#0066ff; font-weight:bold;">@opts</span>.<span style="color:#9900CC;">parse</span>!<span style="color:#006600; font-weight:bold;">&#40;</span>args<span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#0066ff; font-weight:bold;">@files</span> = args</div></div>
<p>Since we are using threads, I open up a thread for STDIN and killed it when we run out of input.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'fcntl'</span><br />
threads = <span style="color:#CC0066; font-weight:bold;">Array</span>.<span style="color:#9900CC;">new</span><br />
<br />
<span style="color:#008000; font-style:italic;"># Set $stdin to be non-blocking</span><br />
<span style="color:#ff6633; font-weight:bold;">$stdin</span>.<span style="color:#9900CC;">fcntl</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#6666ff; font-weight:bold;">Fcntl::F_SETFL</span>,<span style="color:#6666ff; font-weight:bold;">Fcntl::O_NONBLOCK</span><span style="color:#006600; font-weight:bold;">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
<br />
threads<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#CC00FF; font-weight:bold;">Thread</span>.<span style="color:#9900CC;">new</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">begin</span><br />
&nbsp; &nbsp; <span style="color:#ff6633; font-weight:bold;">$stdin</span>.<span style="color:#9900CC;">each_line</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>line<span style="color:#006600; font-weight:bold;">|</span> &nbsp;<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;STDIN: #{line}&quot;</span> <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#CC00FF; font-weight:bold;">Errno</span>::EAGAIN<br />
&nbsp; &nbsp; threads.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;"># Remove this thread since we won't be reading from $stdin</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">run</span></div></div>
<p>Now its time for the files.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#0066ff; font-weight:bold;">@files</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>file<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; threads.<span style="color:#9900CC;">push</span> <span style="color:#CC00FF; font-weight:bold;">Thread</span>.<span style="color:#9900CC;">new</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># do stuff with 'file'</span><br />
&nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<br />
<span style="color:#008000; font-style:italic;"># Put it all together and have the threads run</span><br />
threads.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>thread<span style="color:#006600; font-weight:bold;">|</span> &nbsp;thread.<span style="color:#9900CC;">join</span> <span style="color:#006600; font-weight:bold;">&#125;</span></div></div>
<p>Using these code snippets, you will be able to use input from both files on the command line and STDIN:</p>
<ol>
<li>$ myscript.rb file1 file2</li>
<li>$ cat foo | myscript.rb file1 file2</li>
<li>$ myscript.rb file1 file2 &lt; foo</li>
</ol>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2010/ruby/testing-ruby/should-i-mock-kernel-exit/' rel='bookmark' title='Permanent Link: Should I Mock Kernel#exit'>Should I Mock Kernel#exit</a></li>
<li><a href='http://eric.lubow.org/2009/ruby/parsing-ini-files-with-ruby/' rel='bookmark' title='Permanent Link: Parsing Ini Files With Ruby'>Parsing Ini Files With Ruby</a></li>
<li><a href='http://eric.lubow.org/2009/system-administration/git-branch-name-in-your-bash-prompt/' rel='bookmark' title='Permanent Link: Git Branch Name in Your Bash Prompt'>Git Branch Name in Your Bash Prompt</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2010/ruby/multiple-input-locations-from-bash-into-ruby/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Nagios notify-by-campfire Plugin</title>
		<link>http://eric.lubow.org/2010/system-administration/nagios-notify-by-campfire-plugin/</link>
		<comments>http://eric.lubow.org/2010/system-administration/nagios-notify-by-campfire-plugin/#comments</comments>
		<pubDate>Thu, 06 May 2010 09:45:01 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[System Administration]]></category>
		<category><![CDATA[campfire]]></category>
		<category><![CDATA[nagios]]></category>
		<category><![CDATA[system]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=712</guid>
		<description><![CDATA[Since one of the core communication methods for my company amongst engineers is 37Signals Campfire and Nagios is one of our main monitoring tools for all of our applications and services, I thought it would be a good idea to combine the two. So with a few simple additions to the Nagios configuration and a [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Feric.lubow.org%2F2010%2Fsystem-administration%2Fnagios-notify-by-campfire-plugin%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Feric.lubow.org%2F2010%2Fsystem-administration%2Fnagios-notify-by-campfire-plugin%2F&amp;source=elubow&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>Since one of the core communication methods for my company amongst engineers is <a href="http://37signals.com/">37Signals</a> <a href="http://campfirenow.com/">Campfire</a> and <a href="http://www.nagios.org/">Nagios</a> is one of our main monitoring tools for all of our applications and services, I thought it would be a good idea to combine the two.  So with a few simple additions to the Nagios configuration and a Ruby Campfire script, you can get this up and running.<br />
<span id="more-712"></span><br />
On the Campfire side, I will leave the exercise of adding a Campfire user up to you.  You may need to go through your Campfire administrator for that.</p>
<p>On the Nagios side, the first thing that needs to happen is that you need to add the following commands to your <strong>command.cfg</strong> file in your Nagios configuration.  Make sure that you specify the proper location of your <strong>notify-by-campfire.rb</strong> file.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"># 'notify-host-by-campfire' command definition<br />
define command{<br />
&nbsp; &nbsp; command_name &nbsp; &nbsp;notify-host-by-campfire<br />
&nbsp; &nbsp; command_line &nbsp; &nbsp;/usr/bin/printf &quot;%b&quot; &quot;***** Nagios *****\n\nNotification Type: $NOTIFICATIONTYPE$\nHost: $HOSTNAME$\nState: $HOSTSTATE$\nAddress: $HOSTADDRESS$\nInfo: $HOSTOUTPUT$\n\nDate/Time: $LONGDATETIME$\n&quot; | /usr/local/bin/ruby /usr/local/bin/notify-by-campfire.rb -s &quot;** $NOTIFICATIONTYPE$ Host Alert: $HOSTNAME$ is $HOSTSTATE$ **&quot; <br />
&nbsp; &nbsp; } &nbsp; <br />
<br />
# 'notify-service-by-campfire' command definition<br />
define command{<br />
&nbsp; &nbsp; command_name &nbsp; &nbsp;notify-service-by-campfire<br />
&nbsp; &nbsp; command_line &nbsp; &nbsp;/usr/bin/printf &quot;%b&quot; &quot;***** Nagios *****\n\nNotification Type: $NOTIFICATIONTYPE$\n\nService: $SERVICEDESC$\nHost: $HOSTALIAS$\nAddress: $HOSTADDRESS$\nState: $SERVICESTATE$\n\nDate/Time: $LONGDATETIME$\n\nAdditional Info:\n\n$SERVICEOUTPUT$&quot; | /usr/local/bin/ruby /usr/local/bin/notify-by-campfire.rb -s &quot;** $NOTIFICATIONTYPE$ Service Alert: $HOSTALIAS$/$SERVICEDESC$ is $SERVICESTATE$ **&quot;<br />
&nbsp; &nbsp; }</div></div>
<p>Add this contact template definition for the Campfire contact to your <strong>contacts.cfg</strong>.  Don&#8217;t forget to add it to a <em>contactgroup</em>.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">define contact{<br />
&nbsp; &nbsp; &nbsp; &nbsp; name &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;campfire-contact<br />
&nbsp; &nbsp; &nbsp; &nbsp; service_notification_period &nbsp; &nbsp; 24x7<br />
&nbsp; &nbsp; &nbsp; &nbsp; host_notification_period &nbsp; &nbsp; &nbsp; &nbsp;24x7<br />
&nbsp; &nbsp; &nbsp; &nbsp; service_notification_options &nbsp; &nbsp;w,u,c,r,f,s<br />
&nbsp; &nbsp; &nbsp; &nbsp; host_notification_options &nbsp; &nbsp; &nbsp; d,u,r,f,s<br />
&nbsp; &nbsp; &nbsp; &nbsp; service_notification_commands &nbsp; notify-service-by-campfire<br />
&nbsp; &nbsp; &nbsp; &nbsp; host_notification_commands &nbsp; &nbsp; &nbsp;notify-host-by-campfire<br />
&nbsp; &nbsp; &nbsp; &nbsp; register &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0<br />
&nbsp; &nbsp; &nbsp; &nbsp; }</div></div>
<p>The Ruby code for <strong>notify-by-campfire.rb</strong> is here. Just install it wherever you&#8217;d like and as I said above, make sure its specified properly in your <strong>commands.cfg</strong>.<br />
<script src="http://gist.github.com/387799.js"></script></p>
<p><strong>Note:</strong> I am aware that I could have made this script much shorter, but my goal is to make this extensible should I want to provide more information or change the format.  Feel free to modify for your own usage.</p>
<p><strong>Update (2010-05-17):</strong> To make it a little easier to read in the context of a smaller Campfire window, I have amended the <em>notify-host-by-campfire</em> and <em>notify-service-by-campfire</em> entries to be shorter:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"># 'notify-host-by-campfire' command definition<br />
define command{<br />
&nbsp; &nbsp; command_name &nbsp; &nbsp;notify-host-by-campfire<br />
&nbsp; &nbsp; command_line &nbsp; &nbsp;/usr/bin/printf &quot;%b&quot; &quot;Date/Time: $LONGDATETIME$\n\nHost: $HOSTNAME$\nType/State: $NOTIFICATIONTYPE$/$HOSTSTATE$\n\nInfo: $HOSTOUTPUT$\n\nDate/Time: $LONGDATETIME$\n&quot; | /usr/local/bin/ruby /usr/local/bin/notify-by-campfire.rb -s &quot;** $NOTIFICATIONTYPE$ Host Alert: $HOSTNAME$ ($HOSTADDRESS$) is $HOSTSTATE$ **&quot;<br />
&nbsp; &nbsp; }<br />
<br />
# 'notify-service-by-campfire' command definition<br />
define command{<br />
&nbsp; &nbsp; command_name &nbsp; &nbsp;notify-service-by-campfire<br />
&nbsp; &nbsp; command_line &nbsp; &nbsp;/usr/bin/printf &quot;%b&quot; &quot;Date/Time: $LONGDATETIME$\nType/State: $NOTIFICATIONTYPE$/$SERVICESTATE$\n\n$SERVICEOUTPUT$&quot; | /usr/local/bin/ruby /usr/local/bin/notify-by-campfire.rb -s &quot;** $NOTIFICATIONTYPE$ Service Alert: $HOSTALIAS$/$SERVICEDESC$ ($HOSTADDRESS$) is $SERVICESTATE$ **&quot;<br />
&nbsp; &nbsp; }</div></div>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2010/perl/perl-modules/monitoring-services-with-nagios-plugin/' rel='bookmark' title='Permanent Link: Monitoring Services with Nagios::Plugin'>Monitoring Services with Nagios::Plugin</a></li>
<li><a href='http://eric.lubow.org/2007/perl/syshostname/' rel='bookmark' title='Permanent Link: Sys::Hostname'>Sys::Hostname</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2010/system-administration/nagios-notify-by-campfire-plugin/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
