<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>Reticularium - Linux</title>
  <id>tag:www.reticularium.com,2012:mephisto/linux</id>
  <generator version="0.8.0" uri="http://mephistoblog.com">Mephisto Drax</generator>
  <link href="http://www.reticularium.com/feed/linux/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://www.reticularium.com/linux" rel="alternate" type="text/html"/>
  <updated>2011-12-30T11:20:50+01:00</updated>
  <entry xml:base="http://www.reticularium.com/">
    <author>
      <name>Igor</name>
    </author>
    <id>tag:www.reticularium.com,2011-11-22:2642</id>
    <published>2011-11-22T00:04:00+01:00</published>
    <updated>2011-12-30T11:20:50+01:00</updated>
    <category term="Linux"/>
    <category term="shell"/>
    <category term="unixtime"/>
    <link href="http://www.reticularium.com/2011/11/22/2642" rel="alternate" type="text/html"/>
    <title>Unixtime to date and back conversion</title>
<content type="html">
            &lt;p&gt;Cause of many mistakes. Applies anywhere, I am going to provide a shell examples.&lt;/p&gt;


	&lt;p&gt;So this is what can twist your brain:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;$ date +&amp;quot;%s&amp;quot;&lt;tt&gt;
&lt;/tt&gt;1321920962&lt;tt&gt;
&lt;/tt&gt;$ date -d &amp;quot;1970/01/01 +1321920962 sec&amp;quot; +&amp;quot;%s&amp;quot;&lt;tt&gt;
&lt;/tt&gt;1321917362&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;Unixtime (POSIX time) is a number of seconds passed since the beginning of year 1970. So in the example above I get this number with &lt;code&gt;date +&quot;%s&quot;&lt;/code&gt;, then add this number to the epoch (1970/01/01) and get a different number!&lt;/p&gt;


	&lt;p&gt;The reason of this is very simple:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;$ date -d &amp;quot;1970/01/01&amp;quot; +&amp;quot;%s&amp;quot;&lt;tt&gt;
&lt;/tt&gt;-3600&lt;tt&gt;
&lt;/tt&gt;$ date -u -d &amp;quot;1970/01/01&amp;quot; +&amp;quot;%s&amp;quot;&lt;tt&gt;
&lt;/tt&gt;0&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;&lt;em&gt;Unixtime is always &lt;span class=&quot;caps&quot;&gt;UTC&lt;/span&gt;&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;It is a well-known fact, but it&#8217;s so easy to miss:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;$ date ; date -u&lt;tt&gt;
&lt;/tt&gt;Tue Nov 22 01:31:42 CET 2011&lt;tt&gt;
&lt;/tt&gt;Tue Nov 22 00:31:42 UTC 2011&lt;tt&gt;
&lt;/tt&gt;$ date +&amp;quot;%s&amp;quot; ; date -u +&amp;quot;%s&amp;quot;&lt;tt&gt;
&lt;/tt&gt;1321921903&lt;tt&gt;
&lt;/tt&gt;1321921903&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;That is, for example, you might have local and &lt;span class=&quot;caps&quot;&gt;UTC&lt;/span&gt; datetime variables defined in your code, perfectly distinguishable. And then at some point you decide to just &lt;em&gt;format&lt;/em&gt; it with &lt;code&gt;+&quot;%s&quot;&lt;/code&gt; to unixtime, and they become equal :)&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;BUT&lt;/span&gt;:&lt;/strong&gt;&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;$ dt='Tue Nov 22 01:31:42'&lt;tt&gt;
&lt;/tt&gt;$ date -d &amp;quot;$dt&amp;quot; +&amp;quot;%s&amp;quot;&lt;tt&gt;
&lt;/tt&gt;1321921902&lt;tt&gt;
&lt;/tt&gt;$ date -u -d &amp;quot;$dt&amp;quot; +&amp;quot;%s&amp;quot;&lt;tt&gt;
&lt;/tt&gt;1321925502&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;Note that the second number is bigger. Seems wrong because my local &lt;span class=&quot;caps&quot;&gt;CET&lt;/span&gt; time is one hour ahead. But it is absolutely correct. It is bigger because in the first case to be converted to unixtime this variable must be converted to &lt;span class=&quot;caps&quot;&gt;UTC&lt;/span&gt; first (minus 1 hour), so it becomes &#8216;Tue Nov 22 00:31:42 &lt;span class=&quot;caps&quot;&gt;UTC 2011&lt;/span&gt;&#8217; while in the second case it is considered as &#8216;Tue Nov 22 01:31:42 &lt;span class=&quot;caps&quot;&gt;UTC 2011&lt;/span&gt;&#8217;. In other words, $dt is a string, not a date. This is why the -u option converts it to date like this:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;$ date -d &amp;quot;$dt&amp;quot;&lt;tt&gt;
&lt;/tt&gt;Tue Nov 22 01:31:42 CET 2011&lt;tt&gt;
&lt;/tt&gt;$ date -u -d &amp;quot;$dt&amp;quot;&lt;tt&gt;
&lt;/tt&gt;Tue Nov 22 01:31:42 UTC 2011&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;String can&#8217;t be converted to unixtime, so it is converted to date first, then the result is converted to &lt;span class=&quot;caps&quot;&gt;UTC&lt;/span&gt; if needed and this result is then converted to unixtime.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.reticularium.com/">
    <author>
      <name>Igor</name>
    </author>
    <id>tag:www.reticularium.com,2011-07-31:2232</id>
    <published>2011-07-31T11:16:00+02:00</published>
    <updated>2011-07-31T13:26:23+02:00</updated>
    <category term="Linux"/>
    <category term="Notes"/>
    <category term="Servers"/>
    <category term="backup"/>
    <category term="cloud computing"/>
    <category term="monitoring"/>
    <link href="http://www.reticularium.com/2011/7/31/2232" rel="alternate" type="text/html"/>
    <title>M-Script's new home</title>
<content type="html">
            &lt;p&gt;M-Script project has been moved to its new home: &lt;a href=&quot;http://m-script.org&quot;&gt;http://m-script.org&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;It&#8217;s been under heavy development lately: old scripts have been renewed and enhanced, folders reorganized, files moved to proper locations, default monitors made more informative.&lt;/p&gt;


	&lt;p&gt;It&#8217;s also been published on &lt;a href=&quot;https://github.com/moskit/m-script&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.reticularium.com/">
    <author>
      <name>Igor</name>
    </author>
    <id>tag:www.reticularium.com,2011-06-04:1920</id>
    <published>2011-06-04T21:51:00+02:00</published>
    <updated>2011-06-04T21:58:13+02:00</updated>
    <category term="ERR"/>
    <category term="Linux"/>
    <category term="RoR"/>
    <category term="bash"/>
    <category term="recipe"/>
    <category term="ror"/>
    <category term="ruby"/>
    <link href="http://www.reticularium.com/2011/6/4/1920" rel="alternate" type="text/html"/>
    <title>Gem list -&gt; gem install conversion one-liner</title>
<content type="html">
            &lt;p&gt;Useful to sync gems across servers. Converts &lt;code&gt;gem list --local&lt;/code&gt; output to a bunch of &lt;code&gt;gem install&lt;/code&gt; commands. Rails related gems are removed from the initial list.&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;gem list --local | grep -v '\*' | grep -v ^$ | grep -v ^action | grep -v ^active | grep -v ^rails | grep -v ^rack | grep -v ^rake | sed 's|(|-v=|' | sed 's|)||' | sed 's|^\(.*\),|\1\n\1|' | sed 's|=.*[[:space:]]|=|' | sed 's|^|gem install |'&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
          </content>  </entry>
  <entry xml:base="http://www.reticularium.com/">
    <author>
      <name>Igor</name>
    </author>
    <id>tag:www.reticularium.com,2011-05-31:1359</id>
    <published>2011-05-31T12:28:00+02:00</published>
    <updated>2011-08-15T09:47:56+02:00</updated>
    <category term="ERR"/>
    <category term="Linux"/>
    <category term="RoR"/>
    <category term="binary distros"/>
    <category term="debian"/>
    <category term="gentoo"/>
    <category term="lfs"/>
    <category term="ubuntu"/>
    <link href="http://www.reticularium.com/2011/5/31/1359" rel="alternate" type="text/html"/>
    <title>Why Linux is a pain?</title>
<summary type="html">&lt;p&gt;In fact, it isn&#8217;t. Let me explain.&lt;/p&gt;


	&lt;p&gt;When you see the next time a complaint like this, note what exactly that complaint is related to. I mean operating system. I am sure you&#8217;ll find out that it&#8217;s some sort of binary distributives like Centos or Ubuntu. But &lt;strong&gt;they are not exactly Linux!&lt;/strong&gt; They are what they are: Linux-based operating systems distributable in binary form. You can&#8217;t refer to them as to Linux, because 1) Linux is a kernel, not an operation system, and 2) being a monolithic kernel, it&#8217;s supposed to be carefully configured and compiled natively for each system. And operating system (GNU), should be compiled against this kernel. And the whole toolchain, too.&lt;/p&gt;


	&lt;p&gt;You might say, well, why does it matter? Is there any difference?&lt;/p&gt;


	&lt;p&gt;Yes, there is, and it&#8217;s huge. Let me show you.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;In fact, it isn&#8217;t. Let me explain.&lt;/p&gt;


	&lt;p&gt;When you see the next time a complaint like this, note what exactly that complaint is related to. I mean operating system. I am sure you&#8217;ll find out that it&#8217;s some sort of binary distributives like Centos or Ubuntu. But &lt;strong&gt;they are not exactly Linux!&lt;/strong&gt; They are what they are: Linux-based operating systems distributable in binary form. You can&#8217;t refer to them as to Linux, because 1) Linux is a kernel, not an operation system, and 2) being a monolithic kernel, it&#8217;s supposed to be carefully configured and compiled natively for each system. And operating system (GNU), should be compiled against this kernel. And the whole toolchain, too.&lt;/p&gt;


	&lt;p&gt;You might say, well, why does it matter? Is there any difference?&lt;/p&gt;


	&lt;p&gt;Yes, there is, and it&#8217;s huge. Let me show you.&lt;/p&gt;
&lt;p&gt;In fact, it isn&#8217;t. Let me explain.&lt;/p&gt;


	&lt;p&gt;When you see the next time a complaint like this, note what exactly that complaint is related to. I mean operating system. I am sure you&#8217;ll find out that it&#8217;s some sort of binary distributives like Centos or Ubuntu. But &lt;strong&gt;they are not exactly Linux!&lt;/strong&gt; They are what they are: Linux-based operating systems distributable in binary form. You can&#8217;t refer to them as to Linux, because 1) Linux is a kernel, not an operation system, and 2) being a monolithic kernel, it&#8217;s supposed to be carefully configured and compiled natively for each system. And operating system (GNU), should be compiled against this kernel. And the whole toolchain, too.&lt;/p&gt;


	&lt;p&gt;You might say, well, why does it matter? Is there any difference?&lt;/p&gt;


	&lt;p&gt;Yes, there is, and it&#8217;s huge. Let me show you.&lt;/p&gt;


	&lt;p&gt;There are several aspects of why binary distros are kind of compromizing the idea of &lt;span class=&quot;caps&quot;&gt;GNU&lt;/span&gt;/Linux: performance, security, manageability. Security part is pretty obvious: if you have an operating system that is not just binary compatible, but binary identical with millions of others, it is much easier to create a virus or rootkit infecting such systems. Creating virus for your unique system is just impossible: to create it, attacker needs access to your system. There is a chance of course that a virus will work on your particular system, and this chance is not very small, but attackers don&#8217;t want a chance, they rather distribute their product via certain binary distro related channels to be sure that it runs just fine on every system it gets into.&lt;/p&gt;


	&lt;p&gt;Performance is a long story. I&#8217;d like to get some proper benchmark results first, and I am going to get them. But this is for another article. In short, the more your hardware differs from the one binary distro packages are compiled on, and the more your usage scenario differs from some average scenario, the more performance difference you&#8217;ll get.&lt;/p&gt;


	&lt;p&gt;Manageability looks like the advantage of the binary approach. Pre-compiled software packages are easy to install (just download) and easy to manage via package management system. This is what I want to compare now: how much easier it is, if it is at all.&lt;/p&gt;


	&lt;p&gt;I am going to provide three detailed step-by-step algorithms for setting up a simple &lt;acronym title=&quot;Ruby on Rails&quot;&gt;ROR&lt;/acronym&gt; website on a freshly installed systems: Linux From Scratch&lt;sup&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;, Gentoo&lt;sup&gt;&lt;a href=&quot;#fn2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; and Ubuntu&lt;sup&gt;&lt;a href=&quot;#fn3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;


	&lt;p&gt;So I am going to start from the point where I have a &lt;span class=&quot;caps&quot;&gt;ROR&lt;/span&gt; website copied over to a new server that has a newly installed operating system. This is a common situation: you have your new server just booted up and running and you are going to move your website over to the new server. To shorten the article, I assume that database is already prepared or located on another server. Neither I am going to describe &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; server related steps. All I need is to start the application. So the further steps basically are:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;install Ruby&lt;/li&gt;
		&lt;li&gt;install Rubygems&lt;/li&gt;
		&lt;li&gt;install Rails gem&lt;/li&gt;
		&lt;li&gt;check if the application starts (I&#8217;ll be using script/console for this)&lt;/li&gt;
		&lt;li&gt;fix problems, if any&lt;/li&gt;
	&lt;/ol&gt;


	&lt;h4&gt;Pure &lt;span class=&quot;caps&quot;&gt;GNU&lt;/span&gt;/Linux&lt;/h4&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;Download the source code tarball of required version from ruby-lang.org:&lt;tt&gt;
&lt;/tt&gt;wget ftp://ftp.ruby-lang.org/pub/xxxxxx&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;(if you don't know a certain software download site, Google is your friend, with opensource &lt;tt&gt;
&lt;/tt&gt;software it's never a problem to find the site and get the download link)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;Unpack:&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;tar xf &amp;lt;tarball&amp;gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;cd to directory and run:&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;./configure --help&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;this command shows all available options, I consider three of them needed:&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;./configure --prefix=/usr --enable-shared --enable-pthread&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;Now compile and install:&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;make&lt;tt&gt;
&lt;/tt&gt;make install&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;Now I need Rubygems:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;Download it using the link provided on http://rubyonrails.org/download&lt;tt&gt;
&lt;/tt&gt;Unpack, cd to its directory and run:&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;ruby setup.rb&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;And finally Rails of required version:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;gem install rails -v &amp;lt;version&amp;gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;Now I can switch to the directory where my website is located and run:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;script/console&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;It says there are missing gems. It&#8217;s OK, there is a rake task for this:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;rake gems:install&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;Completes succesfully. That&#8217;s all &#8211; now &lt;code&gt;script/console&lt;/code&gt; loads OK.&lt;/p&gt;


	&lt;h4&gt;Gentoo&lt;/h4&gt;


	&lt;p&gt;With Gentoo, you never need to choose configure script options. Instead, you need to configure the whole system. You only need to do it once, though no problem to adjust any settings later and re-compile affected packages. Basically, you just read the description provided and enable or disable options according to your needs. For example, if you are never going to use X server, you add it to the system-wide configuration with the minus: &lt;code&gt;-X&lt;/code&gt;. From now on no package will ever need X server or X-related libraries as its dependencies. This initial step is quite time-consuming, also it assumes that you are familiar with various software pieces and their relations. But the further management of properly configured system is just like a dream.&lt;/p&gt;


	&lt;p&gt;So here is what my task looks like on Gentoo:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;Compiling and installing Ruby of required version:&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;emerge =ruby-&amp;lt;version&amp;gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;(or just 'emerge ruby', if you want the latest stable version)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;Now Rubygems:&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;emerge rubygems&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;The rest goes as easy as with pure &lt;span class=&quot;caps&quot;&gt;GNU&lt;/span&gt;:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;Rails first. It's available via Portage system, but I prefer to use Rubygems for this:&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;gem install rails -v &amp;lt;version&amp;gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;Checking if it works:&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;script/console&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;Installing missing gems:&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;rake gems:install&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;Done.&lt;/p&gt;


	&lt;h4&gt;Ubuntu&lt;/h4&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;Installing Ruby and Rubygems is easy:&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;apt-get install ruby1.8 rubygems&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;Now Rails:&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;gem install rails -v &amp;lt;version&amp;gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;Easy. Testing the result:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;script/console&lt;tt&gt;
&lt;/tt&gt;  irb not found&lt;tt&gt;
&lt;/tt&gt;???&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;ruby --version&lt;tt&gt;
&lt;/tt&gt;  ruby 1.8.7&lt;tt&gt;
&lt;/tt&gt;irb&lt;tt&gt;
&lt;/tt&gt;  irb: command not found&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;WTH&lt;/span&gt;? Irb is a Ruby shell, it&#8217;s the part of Ruby!&lt;/p&gt;


	&lt;p&gt;In such occasions I use aptitude &#8211; it&#8217;s an interface to Debian package management system. Inside there is a convenient search option. This way, probing various patterns, you can eventually find what package you need. In this case it&#8217;s pretty obvious: the needed package name is irb. But! There is also a package named ruby-full. It&#8217;s a &#8220;virtual&#8221; package made for convenience. You can install it and have everything relating to Ruby. But if you list all the packages it is going to install, you&#8217;ll probably be shocked: it&#8217;s 111 packages, including, for example, hicolor-icon-theme (Gnome desktop icons collection), several libavahi packages (it&#8217;s an automatic network configuration tool), libgl1-mesa-dri (Direct Rendering Infrastructure support for Mesa OpenGL), libxinerama1 (multiple displays support for X server), a lot of X rendering-related libraries including even libxcomposite1 (desktop visual effects support library). I understand that they are needed if you are going to use Ruby for desktop applications development, but using this virtual package to get Ruby properly installed on a web server doesn&#8217;t sound like a good idea.&lt;/p&gt;


	&lt;p&gt;I mention this package for a good reason though: this is a shortest way to find out if there are any other parts of Ruby missing. And yes, reading through those 111 packages I find several other important commands that are parts of Ruby initially, but &lt;code&gt;apt-get install ruby&lt;/code&gt; doesn&#8217;t install them, so I install them now, in a single row:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;apt-get install rake irb rdoc ri&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;Now I run &lt;code&gt;script/console&lt;/code&gt; and it complains about missing gems, as expected.&lt;/p&gt;


	&lt;p&gt;Trying to install them I get:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;rake gems:install&lt;tt&gt;
&lt;/tt&gt;  rake aborted!&lt;tt&gt;
&lt;/tt&gt;  no such file to load -- rspec&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;Ohh, it&#8217;s yet another part of Ruby that has not been installed. Searching by &#8216;rspec&#8217; keyword I find it out:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;apt-get install librspec-ruby1.8&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;Trying again:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;rake gems:install&lt;tt&gt;
&lt;/tt&gt;  rake aborted!&lt;tt&gt;
&lt;/tt&gt;  no such file to load -- mime/types&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;# OK, found:&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;apt-get install libmime-types-ruby&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;and again:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;rake gems:install&lt;tt&gt;
&lt;/tt&gt;  rake aborted!&lt;tt&gt;
&lt;/tt&gt;  no such file to load -- net/https&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;# found, too:&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;apt-get install libopenssl-ruby1.8&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;At last it starts installing gems:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;gem install nokogiri&lt;tt&gt;
&lt;/tt&gt;  ERROR: Failed to build gem native extension.&lt;tt&gt;
&lt;/tt&gt;  extconf.rb:5:in `require': no such file to load -- mkmf (LoadError)&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;With Google help I find that mkmf is a part of ruby-dev package. OK, OK, I suspected I would need it.&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;apt-get install ruby-dev&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;gem install nokogiri&lt;tt&gt;
&lt;/tt&gt;  ERROR: Failed to build gem native extension.&lt;tt&gt;
&lt;/tt&gt;  checking for libxml/parser.h... no&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;If you think that the system has no libxml installed, you are not familiar enough with binary distros:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;apt-get install libxml2&lt;tt&gt;
&lt;/tt&gt;  libxml2 is already the newest version.&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;What it really wants is:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;apt-get install libxml2-dev&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;OK, next round:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;gem install nokogiri&lt;tt&gt;
&lt;/tt&gt;  ERROR: Failed to build gem native extension.&lt;tt&gt;
&lt;/tt&gt;  checking for libxslt/xslt.h... no&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;but I already know what it wants:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;apt-get install libxslt-dev&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;gem install nokogiri&lt;tt&gt;
&lt;/tt&gt;  success&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;Ooophhh!&lt;/p&gt;


	&lt;p&gt;Do you see now how you may come to the conclusion that Linux is a pain? All you need to come to this is:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;to believe that those distros are Linux&lt;/li&gt;
		&lt;li&gt;to need something that the distro of your choice doesn&#8217;t include, or to want this installed &lt;cite&gt;your&lt;/cite&gt; way.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Yes, I could install that ruby-full package and I would have everything I need, but with such approach I would get all systems I am maintaining growing in an uncontrollable manner, let alone unneeded services that might get installed as dependencies, that need to be removed later, otherwise they will be consuming resources and keeping open ports, and each open port is a potential security hole and so on and so on.&lt;/p&gt;


	&lt;p&gt;There exists another point I am argued with from time to time: Red Hat (Ubuntu, whatever) is a well-known and stable brand, and we trust it.&lt;/p&gt;


	&lt;p&gt;Well, yes, I can understand this. They are commercial companies and they care about their brand. But think about this: they rely on something, too. They rely on their upstreams: the developers of open source software. First of all, they rely on Linux and &lt;span class=&quot;caps&quot;&gt;GNU&lt;/span&gt;. Linux and &lt;span class=&quot;caps&quot;&gt;GNU&lt;/span&gt; are the only two brands in Linux world that you can trust absolutely. Otherwise you wouldn&#8217;t use Linux, would you? So what&#8217;s the problem using its pure form rather than something modified?&lt;/p&gt;


	&lt;p&gt;If you think I found a particularly hard case, try to find out how to install rmagick gem on Debian/Ubuntu properly :) This is a &lt;cite&gt;real&lt;/cite&gt; pain.&lt;/p&gt;


	&lt;p&gt;If you think Debian/Ubuntu is bad, it&#8217;s not true. I prefer Debian-based distros over RedHat-based distros. On RedHat and its derivatives you just can&#8217;t find needed packages at all. Or can find packages, but their versions are too old to be usable. So you end up with getting packages from unofficial repositories or even worse &#8211; you have to compile from sources. The latter is a bad idea, because it&#8217;s very probable that some package (similar to abovementioned ruby-full) will want to install the software you have already installed from source as a dependency and you know what? &#8211; it will install it! Package management system doesn&#8217;t know about anything you install without its help. So from its point of view everything will be alright, but in fact the system will be messed up. Of course it&#8217;s not this stupid, there are proper ways: you will need to learn how to use &lt;span class=&quot;caps&quot;&gt;SRPM&lt;/span&gt; and how to create your own packages. But tell me one thing: does it sound easier than using pure &lt;span class=&quot;caps&quot;&gt;GNU&lt;/span&gt;/Linux or Gentoo at least?&lt;/p&gt;


	&lt;p&gt;&lt;sup&gt;1&lt;/sup&gt; &lt;acronym title=&quot;Linux From Scratch&quot;&gt;LFS&lt;/acronym&gt; is not a distribution, it&#8217;s a &lt;a href=&quot;http://www.linuxfromscratch.org&quot;&gt;book of instructions&lt;/a&gt; about compiling pure &lt;span class=&quot;caps&quot;&gt;GNU&lt;/span&gt;/Linux OS from scratch.&lt;/p&gt;


	&lt;p&gt;&lt;sup&gt;2&lt;/sup&gt; Gentoo is more like distribution, but it doesn&#8217;t provide binary packages except those needed as a start point for compiling the whole system. It provides compilation scripts bound by full-featured management system named Portage.&lt;/p&gt;


	&lt;p&gt;&lt;sup&gt;3&lt;/sup&gt; Ubuntu is a very popular Debian-based binary distribution. Its goal is desktop systems primarily, but it&#8217;s being widely used as a server system too. As a Debian derivative, it is a bit more flexible compared to most &lt;acronym title=&quot;originally RedHat Package Manager&quot;&gt;RPM&lt;/acronym&gt;-based distros.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.reticularium.com/">
    <author>
      <name>Igor</name>
    </author>
    <id>tag:www.reticularium.com,2011-05-31:1900</id>
    <published>2011-05-31T07:58:00+02:00</published>
    <updated>2011-06-02T14:44:46+02:00</updated>
    <category term="ERR"/>
    <category term="Linux"/>
    <category term="recipe"/>
    <link href="http://www.reticularium.com/2011/5/31/1900" rel="alternate" type="text/html"/>
    <title>Unmounting rbind mounts</title>
<content type="html">
            &lt;p&gt;Command &lt;code&gt;mount --rbind&lt;/code&gt; mounts recursively, which is handy, but umount has no recursive capabilities, so several umount commands are needed to unmount. The easiest way to do this is to look into /proc/mounts :&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;cat /proc/mounts&lt;/code&gt;&lt;/p&gt;


	&lt;p&gt;Even better:&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;cat /proc/mounts | awk '{print $2}'&lt;/code&gt;&lt;/p&gt;


	&lt;p&gt;Take a look and if you can grep needed mountpoints out of it, just add &lt;code&gt;|grep &amp;lt;something&amp;gt; | sort -r | xargs umount&lt;/code&gt; to the above line.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.reticularium.com/">
    <author>
      <name>Igor</name>
    </author>
    <id>tag:www.reticularium.com,2011-04-24:1718</id>
    <published>2011-04-24T15:38:00+02:00</published>
    <updated>2011-04-24T15:57:19+02:00</updated>
    <category term="ERR"/>
    <category term="Linux"/>
    <category term="bash"/>
    <category term="recipe"/>
    <link href="http://www.reticularium.com/2011/4/24/1718" rel="alternate" type="text/html"/>
    <title>What time is it in.. ?</title>
<content type="html">
            &lt;p&gt;I am used to ask Linux utility &lt;code&gt;date&lt;/code&gt; about everything related to date/time, like &lt;code&gt;date -d &quot;next friday&quot;&lt;/code&gt; or &lt;code&gt;date -d &quot;+245 min&quot;&lt;/code&gt;, but it doesn&#8217;t answer one question I have pretty often: what time is it now in certain timezone?&lt;/p&gt;


	&lt;p&gt;So I had to create a simple script for this:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;#!/bin/bash&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;localtime=`date +&amp;quot;%x %X&amp;quot;`&lt;tt&gt;
&lt;/tt&gt;zonediff=`date -d &amp;quot;$1&amp;quot; +&amp;quot;%H:%M&amp;quot;`&lt;tt&gt;
&lt;/tt&gt;hours=&amp;quot;`echo $zonediff | cut -d':' -f1` hours&amp;quot;&lt;tt&gt;
&lt;/tt&gt;minutes=&amp;quot;`echo $zonediff | cut -d':' -f2` minutes&amp;quot;&lt;tt&gt;
&lt;/tt&gt;date -d &amp;quot;-$hours -$minutes&amp;quot; +&amp;quot;%x %X&amp;quot;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;Zone here is represented by alphabetic abbreviation, that is if you named this script e.g. &#8220;timein&#8221;, you use it like this:&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;timein EDT&lt;/code&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.reticularium.com/">
    <author>
      <name>Igor</name>
    </author>
    <id>tag:www.reticularium.com,2011-01-31:1220</id>
    <published>2011-01-31T00:28:00+01:00</published>
    <updated>2011-04-06T12:50:47+02:00</updated>
    <category term="ERR"/>
    <category term="Linux"/>
    <category term="error"/>
    <category term="gentoo"/>
    <link href="http://www.reticularium.com/2011/1/31/1220" rel="alternate" type="text/html"/>
    <title>Gentoo Coreutils/touch problem hack</title>
<content type="html">
            &lt;p&gt;Old-time problem comes back: coreutils doesn&#8217;t roll back to calls supported by your older kernel. This results in errors like:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;Failed 'touch .unpacked': No such file or directory&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;or:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;Failed 'touch .unpacked': Bad address&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;Funny little helpful hack taken &lt;a href=&quot;http://bugs.gentoo.org/show_bug.cgi?id=224483#c37&quot;&gt;here&lt;/a&gt;&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;mv /bin/touch /bin/oldtouch&lt;tt&gt;
&lt;/tt&gt;echo '#!/bin/sh' &amp;gt; /bin/touch&lt;tt&gt;
&lt;/tt&gt;echo 'echo -n &amp;gt;&amp;gt; &amp;quot;$1&amp;quot;' &amp;gt;&amp;gt; /bin/touch&lt;tt&gt;
&lt;/tt&gt;chmod +x /bin/touch&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;Don&#8217;t forget to restore it back later.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.reticularium.com/">
    <author>
      <name>Igor</name>
    </author>
    <id>tag:www.reticularium.com,2010-09-26:470</id>
    <published>2010-09-26T19:50:00+02:00</published>
    <updated>2010-09-26T19:51:12+02:00</updated>
    <category term="ERR"/>
    <category term="Linux"/>
    <category term="linux"/>
    <category term="lvm"/>
    <category term="recipe"/>
    <link href="http://www.reticularium.com/2010/9/26/470" rel="alternate" type="text/html"/>
    <title>Mounting a logical volume (LVM)</title>
<content type="html">
            &lt;p&gt;&lt;cite&gt;Taken from the &lt;a href=&quot;http://forums.fedoraforum.org/showthread.php?t=165808&quot;&gt;Fedora forum&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;


	&lt;p&gt;..........&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;#modprobe dm-mod&lt;tt&gt;
&lt;/tt&gt;#vgscan&lt;tt&gt;
&lt;/tt&gt;  Reading all physical volumes.  This may take a while...&lt;tt&gt;
&lt;/tt&gt;  Found volume group &amp;quot;VolGroup00&amp;quot; using metadata type lvm2&lt;tt&gt;
&lt;/tt&gt;# vgchange -a y VolGroup00&lt;tt&gt;
&lt;/tt&gt;# lvdisplay&lt;tt&gt;
&lt;/tt&gt;  --- Logical volume ---&lt;tt&gt;
&lt;/tt&gt;  LV Name                /dev/VolGroup00/LogVol01&lt;tt&gt;
&lt;/tt&gt;  VG Name                VolGroup00&lt;tt&gt;
&lt;/tt&gt;. . .&lt;tt&gt;
&lt;/tt&gt;  --- Logical volume ---&lt;tt&gt;
&lt;/tt&gt;  LV Name                /dev/VolGroup00/LogVol00&lt;tt&gt;
&lt;/tt&gt;  VG Name                VolGroup00&lt;tt&gt;
&lt;/tt&gt;# mkdir /mnt/VolGroup00/01&lt;tt&gt;
&lt;/tt&gt;# mount /dev/VolGroup00/LogVol01 /mnt/VolGroup00/01&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;Reference the man pages for lvm, pvdisplay, vgdisplay, lvcreate, lvdisplay, lvextend&lt;/p&gt;


	&lt;p&gt;..........&lt;/p&gt;


	&lt;p&gt;As you can see, you need two things: dm-mod kernel module and &lt;span class=&quot;caps&quot;&gt;LVM2&lt;/span&gt; package (&lt;code&gt;apt-get install lvm2&lt;/code&gt; on Debian, &lt;code&gt;emerge lvm2&lt;/code&gt; on Gentoo and so on)&lt;/p&gt;


	&lt;p&gt;&lt;cite&gt;My personal note:&lt;/cite&gt; LVM provides several useful features but has one huge drawback. If your disk or file system crashes, you won&#8217;t be able to access your &lt;span class=&quot;caps&quot;&gt;LVM&lt;/span&gt; partitions using any liveCD. At least I don&#8217;t know any that would have both dm-mod module and &lt;span class=&quot;caps&quot;&gt;LVM2&lt;/span&gt; package.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.reticularium.com/">
    <author>
      <name>Igor</name>
    </author>
    <id>tag:www.reticularium.com,2010-05-22:223</id>
    <published>2010-05-22T21:18:00+02:00</published>
    <updated>2011-10-12T12:04:13+02:00</updated>
    <category term="ERR"/>
    <category term="Linux"/>
    <category term="bash"/>
    <category term="recipe"/>
    <category term="ruby"/>
    <link href="http://www.reticularium.com/2010/5/22/223" rel="alternate" type="text/html"/>
    <title>CLI scripts templates</title>
<summary type="html">&lt;p&gt;Well, quite self-explanatory. Only Bash and Ruby. Options &#8220;folder&#8221; and &#8220;name&#8221; are examples, replace them with what you need&#8230; Shared in hope this can help someone.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;Well, quite self-explanatory. Only Bash and Ruby. Options &#8220;folder&#8221; and &#8220;name&#8221; are examples, replace them with what you need&#8230; Shared in hope this can help someone.&lt;/p&gt;
&lt;p&gt;Well, quite self-explanatory. Only Bash and Ruby. Options &#8220;folder&#8221; and &#8220;file&#8221; are examples, replace them with what you need&#8230; Shared in hope this can help someone.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Bash template:&lt;/strong&gt;&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;35&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;42&lt;tt&gt;
&lt;/tt&gt;43&lt;tt&gt;
&lt;/tt&gt;44&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;45&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;46&lt;tt&gt;
&lt;/tt&gt;47&lt;tt&gt;
&lt;/tt&gt;48&lt;tt&gt;
&lt;/tt&gt;49&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;50&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;51&lt;tt&gt;
&lt;/tt&gt;52&lt;tt&gt;
&lt;/tt&gt;53&lt;tt&gt;
&lt;/tt&gt;54&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;55&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;56&lt;tt&gt;
&lt;/tt&gt;57&lt;tt&gt;
&lt;/tt&gt;58&lt;tt&gt;
&lt;/tt&gt;59&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;60&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;61&lt;tt&gt;
&lt;/tt&gt;62&lt;tt&gt;
&lt;/tt&gt;63&lt;tt&gt;
&lt;/tt&gt;64&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;#!/usr/bin/env bash&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;possible_options=&amp;quot;folder, file&amp;quot;&lt;tt&gt;
&lt;/tt&gt;necessary_options=&amp;quot;file&amp;quot;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;# The 3 lines below are needed if the script needs other files located in the same folder.&lt;tt&gt;
&lt;/tt&gt;# This finds the real folder even if the script is symlinked.&lt;tt&gt;
&lt;/tt&gt;[ -h $0 ] &amp;amp;&amp;amp; xcommand=`readlink $0` || xcommand=$0&lt;tt&gt;
&lt;/tt&gt;rcommand=${xcommand##*/}   # The real script&lt;tt&gt;
&lt;/tt&gt;rpath=${xcommand%/*}   # The real folder&lt;tt&gt;
&lt;/tt&gt;# Replace the message below with appropriate usage info&amp;quot;&lt;tt&gt;
&lt;/tt&gt;[ &amp;quot;X$*&amp;quot; == &amp;quot;X&amp;quot; ] &amp;amp;&amp;amp; echo &amp;quot;Can't run without options. Possible options are: ${possible_options}&amp;quot; &amp;amp;&amp;amp; exit 1&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;IFS1=$IFS&lt;tt&gt;
&lt;/tt&gt;IFS='--'&lt;tt&gt;
&lt;/tt&gt;for s_option in &amp;quot;${@}&amp;quot;&lt;tt&gt;
&lt;/tt&gt;do&lt;tt&gt;
&lt;/tt&gt;  found=0&lt;tt&gt;
&lt;/tt&gt;  case ${s_option} in&lt;tt&gt;
&lt;/tt&gt;  --*=*)&lt;tt&gt;
&lt;/tt&gt;    s_optname=`expr &amp;quot;X$s_option&amp;quot; : 'X[^-]*-*\([^=]*\)'`  &lt;tt&gt;
&lt;/tt&gt;    s_optarg=`expr &amp;quot;X$s_option&amp;quot; : 'X[^=]*=\(.*\)'` &lt;tt&gt;
&lt;/tt&gt;    ;;&lt;tt&gt;
&lt;/tt&gt;  --*)&lt;tt&gt;
&lt;/tt&gt;    s_optname=`expr &amp;quot;X$s_option&amp;quot; : 'X[^-]*-*\([^=]*\)'`    &lt;tt&gt;
&lt;/tt&gt;    s_optarg='yes' &lt;tt&gt;
&lt;/tt&gt;    ;;&lt;tt&gt;
&lt;/tt&gt;  *=*)&lt;tt&gt;
&lt;/tt&gt;    echo &amp;quot;Wrong syntax: options must start with a double dash&amp;quot;&lt;tt&gt;
&lt;/tt&gt;    exit 1&lt;tt&gt;
&lt;/tt&gt;    ;;&lt;tt&gt;
&lt;/tt&gt;  *)&lt;tt&gt;
&lt;/tt&gt;    s_param=${s_option}&lt;tt&gt;
&lt;/tt&gt;    s_optname=''&lt;tt&gt;
&lt;/tt&gt;    s_optarg=''&lt;tt&gt;
&lt;/tt&gt;    ;;&lt;tt&gt;
&lt;/tt&gt;  esac&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  for option in `echo $possible_options | sed 's/ /--/g'`; do &lt;tt&gt;
&lt;/tt&gt;    [ -n &amp;quot;$s_optname&amp;quot; ] &amp;amp;&amp;amp; [ &amp;quot;X$s_optname&amp;quot; == &amp;quot;X$option&amp;quot; ] &amp;amp;&amp;amp; eval &amp;quot;$option=\&amp;quot;${s_optarg}\&amp;quot;&amp;quot; &amp;amp;&amp;amp; found=1&lt;tt&gt;
&lt;/tt&gt;  done&lt;tt&gt;
&lt;/tt&gt;  [ &amp;quot;X$s_option&amp;quot; == &amp;quot;X$s_param&amp;quot; ] &amp;amp;&amp;amp; found=1&lt;tt&gt;
&lt;/tt&gt;  if [[ found -ne 1 ]]; then &lt;tt&gt;
&lt;/tt&gt;    echo &amp;quot;Unknown option: $s_optname&amp;quot;&lt;tt&gt;
&lt;/tt&gt;    exit 1&lt;tt&gt;
&lt;/tt&gt;  fi&lt;tt&gt;
&lt;/tt&gt;done&lt;tt&gt;
&lt;/tt&gt;found=0&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;for option in `echo $necessary_options | sed 's/,//g'`; do&lt;tt&gt;
&lt;/tt&gt;  [ &amp;quot;X$(eval echo \$$option)&amp;quot; == &amp;quot;X&amp;quot; ] &amp;amp;&amp;amp; missing_options=&amp;quot;${missing_options}, --${option}&amp;quot; &amp;amp;&amp;amp; found=1&lt;tt&gt;
&lt;/tt&gt;done&lt;tt&gt;
&lt;/tt&gt;if [[ found -eq 1 ]]; then&lt;tt&gt;
&lt;/tt&gt;  missing_options=${missing_options#*,}&lt;tt&gt;
&lt;/tt&gt;  echo &amp;quot;Necessary options: ${missing_options} not found&amp;quot;&lt;tt&gt;
&lt;/tt&gt;  exit 1&lt;tt&gt;
&lt;/tt&gt;fi&lt;tt&gt;
&lt;/tt&gt;IFS=$IFS1&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;### Here goes your code&lt;tt&gt;
&lt;/tt&gt;#echo &amp;quot;option folder: ${folder}&amp;quot;&lt;tt&gt;
&lt;/tt&gt;#echo &amp;quot;option file: ${file}&amp;quot;&lt;tt&gt;
&lt;/tt&gt;#echo &amp;quot;parameter: ${s_param}&amp;quot;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;&lt;strong&gt;Ruby template:&lt;/strong&gt;&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;35&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;42&lt;tt&gt;
&lt;/tt&gt;43&lt;tt&gt;
&lt;/tt&gt;44&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;45&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;46&lt;tt&gt;
&lt;/tt&gt;47&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;&lt;span class=&quot;dt&quot;&gt;#!/usr/bin/env ruby&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;possible_options = &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;folder, file&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;necessary_options = &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;options = &lt;span class=&quot;co&quot;&gt;Hash&lt;/span&gt;.new&lt;tt&gt;
&lt;/tt&gt;possible_options.split(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;).each { |po| options[po.strip] = &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt; }&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;co&quot;&gt;File&lt;/span&gt;.symlink?(&lt;span class=&quot;pc&quot;&gt;__FILE__&lt;/span&gt;) ? xcommand = &lt;span class=&quot;co&quot;&gt;File&lt;/span&gt;.readlink(&lt;span class=&quot;pc&quot;&gt;__FILE__&lt;/span&gt;) : xcommand = &lt;span class=&quot;co&quot;&gt;File&lt;/span&gt;.expand_path(&lt;span class=&quot;pc&quot;&gt;__FILE__&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;rcommand = &lt;span class=&quot;co&quot;&gt;File&lt;/span&gt;.basename(xcommand)&lt;tt&gt;
&lt;/tt&gt;rpath = &lt;span class=&quot;co&quot;&gt;File&lt;/span&gt;.dirname(xcommand)&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;begin&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;pc&quot;&gt;ARGV&lt;/span&gt;.empty?&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;c&quot;&gt;# Replace the message below with appropriate usage info&amp;quot;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    raise(&lt;span class=&quot;co&quot;&gt;ArgumentError&lt;/span&gt;, &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Can't run without options. Possible options are: &lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;idl&quot;&gt;#{&lt;/span&gt;possible_options&lt;span class=&quot;idl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;for&lt;/span&gt; s_option &lt;span class=&quot;r&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;pc&quot;&gt;ARGV&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      ((s_option =~ &lt;span class=&quot;rx&quot;&gt;&lt;span class=&quot;dl&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;^--&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;/&lt;/span&gt;&lt;/span&gt;).nil? &lt;span class=&quot;r&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;not&lt;/span&gt; (s_option =~ &lt;span class=&quot;rx&quot;&gt;&lt;span class=&quot;dl&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;/&lt;/span&gt;&lt;/span&gt;).nil?) &lt;span class=&quot;r&quot;&gt;and&lt;/span&gt; raise(&lt;span class=&quot;co&quot;&gt;ArgumentError&lt;/span&gt;, &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Wrong syntax: options must start with a double dash&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;      ((s_option =~ &lt;span class=&quot;rx&quot;&gt;&lt;span class=&quot;dl&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;^--&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;/&lt;/span&gt;&lt;/span&gt;).nil? &lt;span class=&quot;r&quot;&gt;and&lt;/span&gt; (s_option =~ &lt;span class=&quot;rx&quot;&gt;&lt;span class=&quot;dl&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;/&lt;/span&gt;&lt;/span&gt;).nil?) &lt;span class=&quot;r&quot;&gt;and&lt;/span&gt; s_param = s_option&lt;tt&gt;
&lt;/tt&gt;      (s_option =~ &lt;span class=&quot;rx&quot;&gt;&lt;span class=&quot;dl&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;/&lt;/span&gt;&lt;/span&gt;).nil? ? s_optarg = &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;yes&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; : s_optarg = s_option.split(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)[&lt;span class=&quot;i&quot;&gt;1&lt;/span&gt;]&lt;tt&gt;
&lt;/tt&gt;      s_optname = s_option.split(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;)[&lt;span class=&quot;i&quot;&gt;0&lt;/span&gt;].gsub(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;,&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; options.include?(s_optname)&lt;tt&gt;
&lt;/tt&gt;        options[s_optname] = s_optarg&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;r&quot;&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;r&quot;&gt;not&lt;/span&gt; s_param == s_optname&lt;tt&gt;
&lt;/tt&gt;          raise(&lt;span class=&quot;co&quot;&gt;ArgumentError&lt;/span&gt;, &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Unknown option: &lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;idl&quot;&gt;#{&lt;/span&gt;s_optname&lt;span class=&quot;idl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;          exit &lt;span class=&quot;i&quot;&gt;1&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    necessary_options.split(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;).each &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt; |o|&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; options[o.strip].empty?&lt;tt&gt;
&lt;/tt&gt;        raise(&lt;span class=&quot;co&quot;&gt;ArgumentError&lt;/span&gt;, &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Option --&lt;/span&gt;&lt;span class=&quot;il&quot;&gt;&lt;span class=&quot;idl&quot;&gt;#{&lt;/span&gt;o.strip&lt;span class=&quot;idl&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt; is necessary&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;        exit &lt;span class=&quot;i&quot;&gt;1&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;### Here goes your code&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;### note that command-line options are in hash! Address them as e.g. options[&amp;quot;file&amp;quot;]&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;#puts &amp;quot;option folder: #{options[&amp;quot;folder&amp;quot;]}&amp;quot;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;#puts &amp;quot;option file: #{options[&amp;quot;file&amp;quot;]}&amp;quot;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;#puts &amp;quot;parameter: #{s_param}&amp;quot;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;co&quot;&gt;Exception&lt;/span&gt; =&amp;gt; e&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;c&quot;&gt;#  puts e.backtrace&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  puts e.message&lt;tt&gt;
&lt;/tt&gt;  exit &lt;span class=&quot;i&quot;&gt;1&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;I&#8217;d only recommend to expand usage/help information.&lt;/p&gt;


	&lt;p&gt;&lt;cite&gt;Update: you can use method &lt;code&gt;path&lt;/code&gt; instead of &lt;code&gt;expand_path&lt;/code&gt; if it&#8217;s supported by your Ruby version.&lt;/cite&gt;&lt;/p&gt;


	&lt;p&gt;&lt;cite&gt;Update: modified shell template, allowing arguments with spaces, but without non-option parameters:&lt;/cite&gt;&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;35&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;42&lt;tt&gt;
&lt;/tt&gt;43&lt;tt&gt;
&lt;/tt&gt;44&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;45&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;46&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;#!/usr/bin/env bash&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;possible_options=&amp;quot;folder, file&amp;quot;&lt;tt&gt;
&lt;/tt&gt;necessary_options=&amp;quot;file&amp;quot;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;# The 3 lines below are needed if the script needs other files located in the same folder.&lt;tt&gt;
&lt;/tt&gt;# This finds the real folder even if the script is symlinked.&lt;tt&gt;
&lt;/tt&gt;[ -h $0 ] &amp;amp;&amp;amp; xcommand=`readlink $0` || xcommand=$0&lt;tt&gt;
&lt;/tt&gt;rcommand=${xcommand##*/}   # The real script&lt;tt&gt;
&lt;/tt&gt;rpath=${xcommand%/*}   # The real folder&lt;tt&gt;
&lt;/tt&gt;# Replace the message below with appropriate usage info&amp;quot;&lt;tt&gt;
&lt;/tt&gt;[ &amp;quot;X$*&amp;quot; == &amp;quot;X&amp;quot; ] &amp;amp;&amp;amp; echo &amp;quot;Can't run without options. Possible options are: ${possible_options}&amp;quot; &amp;amp;&amp;amp; exit 1&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;ARGV=`echo ${@} | sed 's/^--//' | sed 's/ --/|/g'`&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;IFS1=$IFS&lt;tt&gt;
&lt;/tt&gt;IFS='|'&lt;tt&gt;
&lt;/tt&gt;for s_option in $ARGV&lt;tt&gt;
&lt;/tt&gt;do&lt;tt&gt;
&lt;/tt&gt;  s_optname=${s_option%%=*}&lt;tt&gt;
&lt;/tt&gt;  s_optarg=${s_option##*=}&lt;tt&gt;
&lt;/tt&gt;  [ &amp;quot;X$s_optarg&amp;quot; == &amp;quot;X$s_optname&amp;quot; ] &amp;amp;&amp;amp; s_optarg=&amp;quot;yes&amp;quot;&lt;tt&gt;
&lt;/tt&gt;  for option in `echo $possible_options | sed 's/,//g'`; do &lt;tt&gt;
&lt;/tt&gt;    [ &amp;quot;X$s_optname&amp;quot; == &amp;quot;X$option&amp;quot; ] &amp;amp;&amp;amp; eval &amp;quot;$s_optname=\&amp;quot;$s_optarg\&amp;quot;&amp;quot; &amp;amp;&amp;amp; found=1&lt;tt&gt;
&lt;/tt&gt;  done&lt;tt&gt;
&lt;/tt&gt;  if [[ found -ne 1 ]]; then &lt;tt&gt;
&lt;/tt&gt;    echo &amp;quot;Unknown option: $s_optname&amp;quot;&lt;tt&gt;
&lt;/tt&gt;    exit 1&lt;tt&gt;
&lt;/tt&gt;  fi&lt;tt&gt;
&lt;/tt&gt;done&lt;tt&gt;
&lt;/tt&gt;IFS=$IFS1&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;found=0&lt;tt&gt;
&lt;/tt&gt;for option in `echo $necessary_options | sed 's/ /|/g'`; do&lt;tt&gt;
&lt;/tt&gt;  [ &amp;quot;X$(eval echo \$$option)&amp;quot; == &amp;quot;X&amp;quot; ] &amp;amp;&amp;amp; missing_options=&amp;quot;${missing_options}, --${option}&amp;quot; &amp;amp;&amp;amp; found=1&lt;tt&gt;
&lt;/tt&gt;done&lt;tt&gt;
&lt;/tt&gt;if [[ found -eq 1 ]]; then&lt;tt&gt;
&lt;/tt&gt;  missing_options=${missing_options#*,}&lt;tt&gt;
&lt;/tt&gt;  echo &amp;quot;Necessary options: ${missing_options} not found&amp;quot;&lt;tt&gt;
&lt;/tt&gt;  exit 1&lt;tt&gt;
&lt;/tt&gt;fi&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;### Here goes your code&lt;tt&gt;
&lt;/tt&gt;#echo &amp;quot;option folder: ${folder}&amp;quot;&lt;tt&gt;
&lt;/tt&gt;#echo &amp;quot;option file: ${file}&amp;quot;&lt;tt&gt;
&lt;/tt&gt;#echo &amp;quot;parameter: ${s_param}&amp;quot;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
          </content>  </entry>
  <entry xml:base="http://www.reticularium.com/">
    <author>
      <name>Igor</name>
    </author>
    <id>tag:www.reticularium.com,2010-05-03:222</id>
    <published>2010-05-03T09:11:00+02:00</published>
    <updated>2010-09-07T20:55:41+02:00</updated>
    <category term="ERR"/>
    <category term="Linux"/>
    <category term="recipe"/>
    <category term="vim"/>
    <link href="http://www.reticularium.com/2010/5/3/222" rel="alternate" type="text/html"/>
    <title>Vim auto-comment feature</title>
<content type="html">
            &lt;p&gt;The subject is extremely annoying. I am not that lazy to add a comment symbol myself. This would have been a good idea though, if it wasn&#8217;t sometimes needed to insert blocks of code via clipboard. With auto-comment on, if I insert&lt;/p&gt;


&lt;pre&gt;
some line
# some comment
some line
&lt;/pre&gt;

	&lt;p&gt;I get&lt;/p&gt;


&lt;pre&gt;
some line
# some comment
# some line
&lt;/pre&gt;

	&lt;p&gt;because there is a CR at the end of commented line and the auto-comment function adds the &lt;code&gt;#&lt;/code&gt; symbol to the next line automatically.&lt;/p&gt;


	&lt;p&gt;The real problem begins when you try to insert many lines with some of them commented. You end up with each line after the first comment commented, the next comment commented twice so the next lines all commented twice and so on.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;The solution:&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Add this to your vimrc file:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;au FileType * setl fo-=cro&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;where:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;au = autocmd&lt;/li&gt;
		&lt;li&gt;FileType *  &#8211; any file type&lt;/li&gt;
		&lt;li&gt;setl = setlocal&lt;/li&gt;
		&lt;li&gt;fo = formatoptions&lt;/li&gt;
		&lt;li&gt;-=cro disables c, r and o options ( see &lt;a href=&quot;http://vimdoc.sourceforge.net/htmldoc/change.html#fo-table&quot;&gt;documentation&lt;/a&gt; )&lt;/li&gt;
	&lt;/ul&gt;
          </content>  </entry>
  <entry xml:base="http://www.reticularium.com/">
    <author>
      <name>Igor</name>
    </author>
    <id>tag:www.reticularium.com,2010-04-24:216</id>
    <published>2010-04-24T00:41:00+02:00</published>
    <updated>2010-04-24T00:43:08+02:00</updated>
    <category term="ERR"/>
    <category term="Linux"/>
    <category term="bash"/>
    <category term="linux"/>
    <category term="recipe"/>
    <link href="http://www.reticularium.com/2010/4/24/216" rel="alternate" type="text/html"/>
    <title>Bash and whitespaces in filenames</title>
<summary type="html">&lt;p&gt;This is a really annoying problem we meet pretty often. You can meet it even if you don&#8217;t use Bash. For example, you upload an image named &#8220;my lovely cat.jpg&#8221; to your website and find no image there. Or it has no thumbnail. This may happen because you are using some program for making thumbnails that is being called from, say, &lt;span class=&quot;caps&quot;&gt;PHP&lt;/span&gt; via backtick operator (that is, using unix shell) and that program interprets the file name passed to it as three different command line options: &lt;code&gt;my&lt;/code&gt;, &lt;code&gt;lovely&lt;/code&gt; and &lt;code&gt;cat.jpg&lt;/code&gt;.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;This is a really annoying problem we meet pretty often. You can meet it even if you don&#8217;t use Bash. For example, you upload an image named &#8220;my lovely cat.jpg&#8221; to your website and find no image there. Or it has no thumbnail. This may happen because you are using some program for making thumbnails that is being called from, say, &lt;span class=&quot;caps&quot;&gt;PHP&lt;/span&gt; via backtick operator (that is, using unix shell) and that program interprets the file name passed to it as three different command line options: &lt;code&gt;my&lt;/code&gt;, &lt;code&gt;lovely&lt;/code&gt; and &lt;code&gt;cat.jpg&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This is a really annoying problem we meet pretty often. You can meet it even if you don&#8217;t use Bash. For example, you upload an image named &#8220;my lovely cat.jpg&#8221; to your website and find no image there. Or it has no thumbnail. This may happen because you are using some program for making thumbnails that is being called from, say, &lt;span class=&quot;caps&quot;&gt;PHP&lt;/span&gt; via backtick operator (that is, using unix shell) and that program interprets the file name passed to it as three different command line options: &lt;code&gt;my&lt;/code&gt;, &lt;code&gt;lovely&lt;/code&gt; and &lt;code&gt;cat.jpg&lt;/code&gt;.&lt;/p&gt;


	&lt;p&gt;Well, cases like this are simple to avoid, just add double quotes, like this: &lt;code&gt;yourthumbnailer &quot;$filename&quot;&lt;/code&gt;, and your &#8220;my lovely bash.jpg&#8221; will be processed. Err, I meant &#8220;my lovely cat.jpg&#8221;, not going to correct it, it&#8217;s funny :)&lt;/p&gt;


	&lt;p&gt;But there may be more complex issues. And fortunately there are plenty of methods to deal with those issues.&lt;/p&gt;


I am far from an idea to describe all possible methods, so just a few examples, hopefully useful. Anyways, all methods are based on same ideas, and I proudly know the three of them:
	&lt;ol&gt;
	&lt;li&gt;null character termination built into some utilities (e.g. find) to avoid special treatment of all special characters including whitespaces&lt;/li&gt;
		&lt;li&gt;using double quotes where applicable&lt;/li&gt;
		&lt;li&gt;using &lt;span class=&quot;caps&quot;&gt;IFS&lt;/span&gt; variable&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Here&#8217;s the examples.&lt;/p&gt;


	&lt;p&gt;Idea #1&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;$ mkdir &amp;quot;test 1&amp;quot;&lt;tt&gt;
&lt;/tt&gt;$ touch test\ 1/some\ file   # created &amp;quot;test 1&amp;quot; folder with file &amp;quot;some file&amp;quot; inside&lt;tt&gt;
&lt;/tt&gt;# here is the problem:&lt;tt&gt;
&lt;/tt&gt;$ find -name &amp;quot;test*&amp;quot; | xargs ls&lt;tt&gt;
&lt;/tt&gt;ls: cannot access ./test: No such file or directory&lt;tt&gt;
&lt;/tt&gt;ls: cannot access 1: No such file or directory&lt;tt&gt;
&lt;/tt&gt;# checking if the find part works:&lt;tt&gt;
&lt;/tt&gt;$ find -name &amp;quot;test*&amp;quot;&lt;tt&gt;
&lt;/tt&gt;./test 1   # works perfectly&lt;tt&gt;
&lt;/tt&gt;# trying the -0 option for xargs that enables null character termination:&lt;tt&gt;
&lt;/tt&gt;$ find -name &amp;quot;test*&amp;quot; | xargs -0 ls&lt;tt&gt;
&lt;/tt&gt;ls: cannot access ./test 1    # doesn't work, but note the difference:&lt;tt&gt;
&lt;/tt&gt;: No such file or directory   # now it considers &amp;quot;test 1&amp;quot; a single folder&lt;tt&gt;
&lt;/tt&gt;# what is needed is null character termination on both ends of the pipe:&lt;tt&gt;
&lt;/tt&gt;$ find -name &amp;quot;test*&amp;quot; -print0 | xargs -0 ls&lt;tt&gt;
&lt;/tt&gt;some file   # works perfectly now&lt;tt&gt;
&lt;/tt&gt;# using find's built-in -exec feature is often preferrable:&lt;tt&gt;
&lt;/tt&gt;$ find -name &amp;quot;test*&amp;quot; -exec ls '{}' \;&lt;tt&gt;
&lt;/tt&gt;some file   # works just fine without null character termination&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;Idea #2&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;$ for dir in test*; do echo $dir; ls $dir; done&lt;tt&gt;
&lt;/tt&gt;test 1    # note that echo $dir works, so it's assigned correctly&lt;tt&gt;
&lt;/tt&gt;ls: cannot access test: No such file or directory   # ls $dir doesn't work&lt;tt&gt;
&lt;/tt&gt;ls: cannot access 1: No such file or directory      # double quotes are needed&lt;tt&gt;
&lt;/tt&gt;$ for dir in test*; do echo &amp;quot;$dir&amp;quot;; ls &amp;quot;$dir&amp;quot;; done&lt;tt&gt;
&lt;/tt&gt;test 1&lt;tt&gt;
&lt;/tt&gt;some file&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;Idea #3&lt;/p&gt;


	&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;IFS&lt;/span&gt; is a system variable, it stands for &#8220;Internal Field Separator&#8221;. &#8220;I Feel Stupid&#8221; is a good match, too, because the idea to use &lt;span class=&quot;caps&quot;&gt;IFS&lt;/span&gt; often comes after a long time spent for escaping and quoting and many lines of unneeded code written. By default, &lt;span class=&quot;caps&quot;&gt;IFS&lt;/span&gt; is set to a tab, newline and space bound together so any of these works as a field separator.&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;$ (IFS='';for dir in test*; do echo $dir; ls $dir; done) # parenthesis needed&lt;tt&gt;
&lt;/tt&gt;test 1                                           # to run this in a subshell leaving&lt;tt&gt;
&lt;/tt&gt;some file                                        # the original IFS untouched&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;More complex example:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;$ mypath=&amp;quot;test 1/test 2/test 3&amp;quot;  # some recursive folders, each needs to&lt;tt&gt;
&lt;/tt&gt;$ for folder in $mypath; do echo $folder; done         # be processed&lt;tt&gt;
&lt;/tt&gt;test                                           # I am simulating processing&lt;tt&gt;
&lt;/tt&gt;1/test                                       # these folders with the echo&lt;tt&gt;
&lt;/tt&gt;2/test                                       # command. Apparently the result&lt;tt&gt;
&lt;/tt&gt;3                                              # is not what we wanted&lt;tt&gt;
&lt;/tt&gt;$ IFS1=$IFS; IFS='/'; for folder in $mypath; do echo $folder; done; IFS=$IFS1&lt;tt&gt;
&lt;/tt&gt;test 1&lt;tt&gt;
&lt;/tt&gt;test 2&lt;tt&gt;
&lt;/tt&gt;test 3&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;I used &lt;span class=&quot;caps&quot;&gt;IFS&lt;/span&gt; reassigning here instead of subshell, this way you can use it in scripts reassigning at the beginning and assigning back at the end or for some part of code where needed.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.reticularium.com/">
    <author>
      <name>Igor</name>
    </author>
    <id>tag:www.reticularium.com,2010-04-08:204</id>
    <published>2010-04-08T21:22:00+02:00</published>
    <updated>2010-04-08T21:36:05+02:00</updated>
    <category term="ERR"/>
    <category term="Linux"/>
    <category term="bash"/>
    <category term="reference"/>
    <link href="http://www.reticularium.com/2010/4/8/204" rel="alternate" type="text/html"/>
    <title>Strings splitting in Bash</title>
<summary type="html">&lt;p&gt;It&#8217;s not easy to remember, so here&#8217;s the reference.&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;var=aaa.bbb.ccc&lt;/code&gt;&lt;/p&gt;


	&lt;table&gt;
		&lt;tr&gt;
			  &amp;nbsp;       
			  &lt;code&gt;%&lt;/code&gt;                                              
			 &lt;code&gt;%%&lt;/code&gt;                                               
			 &lt;code&gt;#&lt;/code&gt;                                               
			 &lt;code&gt;##&lt;/code&gt;    
		&lt;/tr&gt;
		&lt;tr&gt;
			 &amp;nbsp; &lt;code&gt;.*&lt;/code&gt;&amp;nbsp; 
			&lt;td&gt;&lt;code&gt;${var%.*} =&amp;gt; aaa.bbb&lt;/code&gt;                            &lt;/td&gt;
			&lt;td&gt;&lt;code&gt;${var%%.*} =&amp;gt; aaa&lt;/code&gt;                                   &lt;/td&gt;
			&lt;td&gt;&lt;code&gt;${var#.*} =&amp;gt; aaa.bbb.ccc&lt;/code&gt; (doesn&#8217;t work)&lt;/td&gt;
			&lt;td&gt;&lt;code&gt;${var##.*} =&amp;gt; aaa.bbb.ccc&lt;/code&gt; (doesn&#8217;t work)&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			 &amp;nbsp; &lt;code&gt;*.&lt;/code&gt;&amp;nbsp; 
			&lt;td&gt;&lt;code&gt;${var%*.} =&amp;gt; aaa.bbb.ccc&lt;/code&gt; (doesn&#8217;t work)&lt;/td&gt;
			&lt;td&gt;&lt;code&gt;${var%%*.} =&amp;gt; aaa.bbb.ccc&lt;/code&gt; (doesn&#8217;t work)&lt;/td&gt;
			&lt;td&gt;&lt;code&gt;${var#*.} =&amp;gt; bbb.ccc&lt;/code&gt;                              &lt;/td&gt;
			&lt;td&gt;&lt;code&gt;${var##*.} =&amp;gt; ccc&lt;/code&gt;      &lt;/td&gt;
		&lt;/tr&gt;
	&lt;/table&gt;</summary><content type="html">
            &lt;p&gt;It&#8217;s not easy to remember, so here&#8217;s the reference.&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;var=aaa.bbb.ccc&lt;/code&gt;&lt;/p&gt;


	&lt;table&gt;
		&lt;tr&gt;
			  &amp;nbsp;       
			  &lt;code&gt;%&lt;/code&gt;                                              
			 &lt;code&gt;%%&lt;/code&gt;                                               
			 &lt;code&gt;#&lt;/code&gt;                                               
			 &lt;code&gt;##&lt;/code&gt;    
		&lt;/tr&gt;
		&lt;tr&gt;
			 &amp;nbsp; &lt;code&gt;.*&lt;/code&gt;&amp;nbsp; 
			&lt;td&gt;&lt;code&gt;${var%.*} =&amp;gt; aaa.bbb&lt;/code&gt;                            &lt;/td&gt;
			&lt;td&gt;&lt;code&gt;${var%%.*} =&amp;gt; aaa&lt;/code&gt;                                   &lt;/td&gt;
			&lt;td&gt;&lt;code&gt;${var#.*} =&amp;gt; aaa.bbb.ccc&lt;/code&gt; (doesn&#8217;t work)&lt;/td&gt;
			&lt;td&gt;&lt;code&gt;${var##.*} =&amp;gt; aaa.bbb.ccc&lt;/code&gt; (doesn&#8217;t work)&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			 &amp;nbsp; &lt;code&gt;*.&lt;/code&gt;&amp;nbsp; 
			&lt;td&gt;&lt;code&gt;${var%*.} =&amp;gt; aaa.bbb.ccc&lt;/code&gt; (doesn&#8217;t work)&lt;/td&gt;
			&lt;td&gt;&lt;code&gt;${var%%*.} =&amp;gt; aaa.bbb.ccc&lt;/code&gt; (doesn&#8217;t work)&lt;/td&gt;
			&lt;td&gt;&lt;code&gt;${var#*.} =&amp;gt; bbb.ccc&lt;/code&gt;                              &lt;/td&gt;
			&lt;td&gt;&lt;code&gt;${var##*.} =&amp;gt; ccc&lt;/code&gt;      &lt;/td&gt;
		&lt;/tr&gt;
	&lt;/table&gt;
&lt;p&gt;It&#8217;s not easy to remember, so here&#8217;s the reference.&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;%&lt;/code&gt; means &#8220;right&#8221;&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;#&lt;/code&gt; means &#8220;left&#8221;&lt;/p&gt;


	&lt;p&gt;(look at the keyboard if you forgot, these signs relative positions can remind their meaning)&lt;/p&gt;


	&lt;p&gt;single sign means &#8220;the first&#8221;, double sign means &#8220;the last&#8221;.&lt;/p&gt;


	&lt;p&gt;So, a single &lt;code&gt;%&lt;/code&gt; means &#8220;the first starting from right&#8221;, a double &lt;code&gt;##&lt;/code&gt; means &#8220;the last starting from left&#8221;.&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;.*&lt;/code&gt; means &#8220;everything on the right from the dot&#8221;. Instead of the dot any other symbol can be used. Nothing can be used instead of the asterisk symbol it seems, at least I couldn&#8217;t find anything.&lt;/p&gt;


	&lt;p&gt;Similarly, &lt;code&gt;*.&lt;/code&gt; means &#8220;everything on the left form the dot&#8221;&lt;/p&gt;


	&lt;p&gt;Let&#8217;s assign &lt;code&gt;var=aaa.bbb.ccc&lt;/code&gt;&lt;/p&gt;


	&lt;p&gt;There are 8 possible combinations, but not all of them work:&lt;/p&gt;


	&lt;table&gt;
		&lt;tr&gt;
			  &amp;nbsp;       
			  &lt;code&gt;%&lt;/code&gt;                                              
			 &lt;code&gt;%%&lt;/code&gt;                                               
			 &lt;code&gt;#&lt;/code&gt;                                               
			 &lt;code&gt;##&lt;/code&gt;    
		&lt;/tr&gt;
		&lt;tr&gt;
			 &amp;nbsp; &lt;code&gt;.*&lt;/code&gt;&amp;nbsp; 
			&lt;td&gt;&lt;code&gt;${var%.*} =&amp;gt; aaa.bbb&lt;/code&gt;                            &lt;/td&gt;
			&lt;td&gt;&lt;code&gt;${var%%.*} =&amp;gt; aaa&lt;/code&gt;                                   &lt;/td&gt;
			&lt;td&gt;&lt;code&gt;${var#.*} =&amp;gt; aaa.bbb.ccc&lt;/code&gt; (doesn&#8217;t work)&lt;/td&gt;
			&lt;td&gt;&lt;code&gt;${var##.*} =&amp;gt; aaa.bbb.ccc&lt;/code&gt; (doesn&#8217;t work)&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			 &amp;nbsp; &lt;code&gt;*.&lt;/code&gt;&amp;nbsp; 
			&lt;td&gt;&lt;code&gt;${var%*.} =&amp;gt; aaa.bbb.ccc&lt;/code&gt; (doesn&#8217;t work)&lt;/td&gt;
			&lt;td&gt;&lt;code&gt;${var%%*.} =&amp;gt; aaa.bbb.ccc&lt;/code&gt; (doesn&#8217;t work)&lt;/td&gt;
			&lt;td&gt;&lt;code&gt;${var#*.} =&amp;gt; bbb.ccc&lt;/code&gt;                              &lt;/td&gt;
			&lt;td&gt;&lt;code&gt;${var##*.} =&amp;gt; ccc&lt;/code&gt;                                   &lt;/td&gt;
		&lt;/tr&gt;
	&lt;/table&gt;




	&lt;p&gt;Here&#8217;s the example.&lt;/p&gt;


	&lt;p&gt;The code below cuts off sub-domains and returns domain name (2nd level domain), e.g. abc.def.example.com -&amp;gt; example.com&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;domain2l=`a12=${domain%.*} ; a3=${domain##*.} ; a2=${a12##*.} ; echo &amp;quot;$a2.$a3&amp;quot;`&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;where &lt;code&gt;domain&lt;/code&gt; is any domain name with any number of sub-domains, and &lt;code&gt;domain2l&lt;/code&gt; is a resulting 2nd level domain.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.reticularium.com/">
    <author>
      <name>Igor</name>
    </author>
    <id>tag:www.reticularium.com,2010-02-26:179</id>
    <published>2010-02-26T10:47:00+01:00</published>
    <updated>2010-02-26T13:06:29+01:00</updated>
    <category term="ERR"/>
    <category term="Linux"/>
    <category term="bash"/>
    <category term="linux"/>
    <category term="recipe"/>
    <link href="http://www.reticularium.com/2010/2/26/179" rel="alternate" type="text/html"/>
    <title>find vs ls</title>
<summary type="html">&lt;p&gt;I was doing a simple test of pwgen (handy utility to generate passwords) and since this test was creating a lot of files in a folder I decided to combine it with a test of ls speed vs find speed:&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;I was doing a simple test of pwgen (handy utility to generate passwords) and since this test was creating a lot of files in a folder I decided to combine it with a test of ls speed vs find speed:&lt;/p&gt;
&lt;p&gt;I was doing a simple test of pwgen (handy utility to generate passwords) and since this test was creating a lot of files in a folder I decided to combine it with a test of ls speed vs find speed:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;homemain ~ # mkdir test&lt;tt&gt;
&lt;/tt&gt;homemain ~ # for ((i=1; i&amp;lt;=300; i++)); do for pw in `pwgen -C`; do touch test/${pw}; done; done&lt;tt&gt;
&lt;/tt&gt;homemain ~ # time (ls test|wc -l)&lt;tt&gt;
&lt;/tt&gt;47685&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;real  0m0.152s&lt;tt&gt;
&lt;/tt&gt;user  0m0.148s&lt;tt&gt;
&lt;/tt&gt;sys  0m0.008s&lt;tt&gt;
&lt;/tt&gt;homemain ~ # time (find test -type f|wc -l)&lt;tt&gt;
&lt;/tt&gt;47685&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;real  0m0.072s&lt;tt&gt;
&lt;/tt&gt;user  0m0.024s&lt;tt&gt;
&lt;/tt&gt;sys  0m0.048s&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;Well, find is faster in mere files listing. On folders with files having more complicated names and differing in size and other attributes the difference is much more significant.&lt;/p&gt;


	&lt;p&gt;I repeated the time measurement part several times to check if any caching involved, but found no difference.&lt;/p&gt;


	&lt;p&gt;Ahh, about pwgen: there should be 48000 files. So 48000 &#8211; 47685 = 315 filenames appeared to be not unique. Not that bad given that it is a default simple passwords that are easy to remember (e.g. doo5maiJ) without additional symbols etc. The utility has options to make password more secure, I didn&#8217;t test it. This pwgen test didn&#8217;t have any practical meaning, just curiosity :)&lt;/p&gt;


	&lt;p&gt;The &#8216;find vs ls&#8217; test has much more practical meaning though. The result means that in scripts it is much better to use find rather than ls. The &#8216;find&#8217; utility at the first glance is something more complicated than a &#8220;simple&#8221; ls. But ls checks and outputs more information about each file and therefore is slower.&lt;/p&gt;


	&lt;p&gt;Another practical outcome is a simple wrapper equivalent to &#8216;ls -l&#8217;. I found it useful to read e.g. mail folders containing a huge amount of messages:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;#!/bin/sh&lt;tt&gt;
&lt;/tt&gt;find $1 -maxdepth 1 -ls&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;or copy and paste my command sequence:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;cat &amp;gt; /usr/local/bin/fls &amp;lt;&amp;lt; &amp;quot;EOF&amp;quot;&lt;tt&gt;
&lt;/tt&gt;#!/bin/sh&lt;tt&gt;
&lt;/tt&gt;find $1 -maxdepth 1 -ls&lt;tt&gt;
&lt;/tt&gt;EOF&lt;tt&gt;
&lt;/tt&gt;chmod 755 /usr/local/bin/fls&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;


	&lt;p&gt;Doing a test:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;homemain ~ # time (fls test|wc -l)&lt;tt&gt;
&lt;/tt&gt;47686&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;real  0m0.218s&lt;tt&gt;
&lt;/tt&gt;user  0m0.140s&lt;tt&gt;
&lt;/tt&gt;sys  0m0.076s&lt;tt&gt;
&lt;/tt&gt;homemain ~ # time (ls -l test|wc -l)&lt;tt&gt;
&lt;/tt&gt;47686&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;real  0m0.366s&lt;tt&gt;
&lt;/tt&gt;user  0m0.228s&lt;tt&gt;
&lt;/tt&gt;sys  0m0.136s&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
          </content>  </entry>
  <entry xml:base="http://www.reticularium.com/">
    <author>
      <name>Igor</name>
    </author>
    <id>tag:www.reticularium.com,2010-02-07:169</id>
    <published>2010-02-07T12:15:00+01:00</published>
    <updated>2010-02-07T12:35:11+01:00</updated>
    <category term="ERR"/>
    <category term="Linux"/>
    <category term="desktop"/>
    <category term="gnome"/>
    <category term="linux"/>
    <category term="recipe"/>
    <link href="http://www.reticularium.com/2010/2/7/169" rel="alternate" type="text/html"/>
    <title>Enabling Gnome composite extension</title>
<content type="html">
            &lt;p&gt;For some reason there is no obvious way to enable it (Gnome 2.26.3)&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Open GConf editor: Applications -&amp;gt; System Tools -&amp;gt; Configuration Editor&lt;/li&gt;
		&lt;li&gt;apps -&amp;gt; metacity -&amp;gt; general -&amp;gt; compositing manager (check box there)&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;That&#8217;s all. Enjoy numerous visual effects like shadows, real transparency (underlying windows become visible) etc.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.reticularium.com/">
    <author>
      <name>Igor</name>
    </author>
    <id>tag:www.reticularium.com,2010-02-02:168</id>
    <published>2010-02-02T22:12:00+01:00</published>
    <updated>2011-01-25T22:43:07+01:00</updated>
    <category term="ERR"/>
    <category term="Linux"/>
    <category term="Servers"/>
    <category term="mysql"/>
    <link href="http://www.reticularium.com/2010/2/2/168" rel="alternate" type="text/html"/>
    <title>MySQL export to CSV</title>
<content type="html">
            &lt;p&gt;Pretty easy:&lt;/p&gt;


&lt;div&gt;
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td title=&quot;double click to expand&quot; class=&quot;code&quot; alt=&quot;double click to expand&quot;&gt;&lt;pre&gt;mysql -u&amp;lt;username&amp;gt; -p&amp;lt;password&amp;gt; &amp;lt;dbname&amp;gt; -B -e &amp;quot;select * from &amp;lt;tablename&amp;gt;&amp;quot; | sed 's/\t/&amp;quot;,&amp;quot;/g;s/^/&amp;quot;/;s/$/&amp;quot;/;s/\n//g' &amp;gt; &amp;lt;filename.csv&amp;gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
          </content>  </entry>
</feed>

