<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" gd:etag="W/&quot;DU8GQXg5eyp7ImA9WxNUGU0.&quot;"><id>tag:blogger.com,1999:blog-32637828</id><updated>2009-11-11T02:50:20.623Z</updated><title>fahd.blog</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/" /><link rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>121</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="self" href="http://feeds.feedburner.com/Fahdblog" type="application/atom+xml" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">Fahdblog</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry gd:etag="W/&quot;DEcCQno7eCp7ImA9WxNVEU4.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-1742493535549571857</id><published>2009-10-21T15:41:00.000+01:00</published><updated>2009-10-21T15:41:03.400+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-21T15:41:03.400+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="UNIX" /><category scheme="http://www.blogger.com/atom/ns#" term="bash" /><category scheme="http://www.blogger.com/atom/ns#" term="globbing" /><category scheme="http://www.blogger.com/atom/ns#" term="shell" /><title>Bash Globbing</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
Globbing refers to the expansion of shell metacharacters to complete file names. For example, when you run &lt;code&gt;ls *&lt;/code&gt;, the shell expands the wildcard * into a list of files and passes them as arguments to &lt;code&gt;ls&lt;/code&gt;.

&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;b&gt;sharfah@starship:~&amp;gt;&lt;/b&gt; ls *
&lt;font color="green"&gt;file1 File2&lt;/font&gt;&lt;/pre&gt;

&lt;b&gt;&lt;font color="#000099"&gt;Dot Globbing&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
By default, Bash does not glob dot-files. This means that &lt;code&gt;ls *&lt;/code&gt; will not pick up any files beginning with the dot (.) character. However, it is easy to change this by doing the following:

&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;b&gt;sharfah@starship:~&amp;gt;&lt;/b&gt; shopt -s dotglob
&lt;b&gt;sharfah@starship:~&amp;gt;&lt;/b&gt; ls *
&lt;font color="green"&gt;.dotFile1 file1 File2&lt;/font&gt;
&lt;/pre&gt;

&lt;b&gt;&lt;font color="#000099"&gt;Case-Insensitive Globbing&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
There is also an option to turn on case-insensitive globbing:
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;b&gt;sharfah@starship:~&amp;gt;&lt;/b&gt; shopt -s nocaseglob
&lt;b&gt;sharfah@starship:~&amp;gt;&lt;/b&gt; ls f*
&lt;font color="green"&gt;file1 File2&lt;/font&gt;
&lt;/pre&gt;

To view a list of all your shell options, type &lt;code&gt;shopt&lt;/code&gt;.

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-1742493535549571857?l=fahdshariff.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/1742493535549571857/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2009/10/bash-globbing.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/1742493535549571857?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/1742493535549571857?v=2" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/2009/10/bash-globbing.html" title="Bash Globbing" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11444574926882287120" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;C0cFQnk8fyp7ImA9WxNWFUk.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-3578075035574335401</id><published>2009-10-14T18:23:00.000+01:00</published><updated>2009-10-14T18:23:33.777+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-14T18:23:33.777+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="eclipse" /><category scheme="http://www.blogger.com/atom/ns#" term="debug" /><title>Remote Debugging Java Applications</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
This is a quick post to show how you can connect to a remote Java virtual machine for debugging. I'm always forgetting the properties!
&lt;p/&gt;

&lt;b&gt;&lt;font color="#000099"&gt;1. Add JVM Properties&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
Add the following properties to your java process before starting it up. This will tell it to accept debug connections.

&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;font color="green"&gt;-Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=4001,suspend=y&lt;/font&gt;&lt;/pre&gt;

&lt;b&gt;&lt;font color="#000099"&gt;2. Connect to Remote JVM through Eclipse&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
&lt;ul&gt;
&lt;li&gt;Go to your Eclipse Debug Configurations and create a new &lt;i&gt;Remote Java Application&lt;/i&gt; configuration.&lt;/li&gt;
&lt;li&gt;In Connection Type, choose &lt;i&gt;Standard (Socket Attach)&lt;/i&gt;. &lt;/li&gt;
&lt;li&gt;Set the host to the machine where your Java application is running.&lt;/li&gt;
&lt;li&gt;Set the port to the debug port specified in the JVM properties e.g. 4001.&lt;/li&gt;
&lt;li&gt;Press &lt;i&gt;Debug&lt;/i&gt; to start debugging.&lt;/li&gt;
&lt;/ul&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-3578075035574335401?l=fahdshariff.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/3578075035574335401/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2009/10/remote-debugging-java-applications.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/3578075035574335401?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/3578075035574335401?v=2" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/2009/10/remote-debugging-java-applications.html" title="Remote Debugging Java Applications" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11444574926882287120" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DUYHQ3Y5fip7ImA9WxNXFEo.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-606507096153480979</id><published>2009-10-02T10:52:00.000+01:00</published><updated>2009-10-02T10:52:12.826+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-02T10:52:12.826+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="logging" /><category scheme="http://www.blogger.com/atom/ns#" term="log4j" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>Using log4j's FallbackErrorHandler</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
Our applications currently use a &lt;a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/DailyRollingFileAppender.html"&gt;DailyRollingFileAppender&lt;/a&gt; for logging, but since they run on NFS across a number of different servers, we quite often get errors due to stale NFS file handles, when &lt;a href="http://logging.apache.org/log4j/1.2/index.html"&gt;log4j&lt;/a&gt; tries to write to the files. We sometimes also get errors if the logging mount point is missing on some of the servers.
&lt;p/&gt;
I've been trying to find a way to switch to a different appender (such as a &lt;a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/ConsoleAppender.html"&gt;ConsoleAppender&lt;/a&gt;), if log4j fails to write to the log files. At first I thought of writing my own custom appender, to wrap up a FileAppender and a ConsoleAppender, and to switch to the ConsoleAppender if the FileAppender threw an IOException, but then I came across the &lt;a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/varia/FallbackErrorHandler.html"&gt;FallbackErrorHandler&lt;/a&gt;, which allows you to configure a backup appender, which takes over if the primary appender fails for whatever reason.
&lt;p/&gt;
This is how you can set up your log4j.xml file to use a &lt;code&gt;FallbackErrorHandler&lt;/code&gt;:

&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;1. Create a backup appender:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;

The backup appender will be used if the primary appender fails. My backup is a &lt;code&gt;ConsoleAppender&lt;/code&gt;:

&lt;pre class="brush:xml; gutter:false;"&gt;
  &amp;lt;appender name="console" class="org.apache.log4j.ConsoleAppender"&amp;gt;
    &amp;lt;param name="Target" value="System.out"/&amp;gt;
    &amp;lt;layout class="org.apache.log4j.PatternLayout"&amp;gt;
      &amp;lt;param name="ConversionPattern" value="%d %-5p %30.30c - %m%n"/&amp;gt;
    &amp;lt;/layout&amp;gt;
  &amp;lt;/appender&amp;gt;
&lt;/pre&gt;

&lt;b&gt;&lt;font color="#000099"&gt;2. Add a FallbackErrorHandler to your primary appender:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;

My primary appender is a &lt;code&gt;DailyRollingFileAppender&lt;/code&gt;. Add a &lt;code&gt;FallbackErrorHandler&lt;/code&gt; to it and tell it to use the "console" (backup) appender, using the &lt;code&gt;appender-ref&lt;/code&gt; tag. The &lt;code&gt;root-ref&lt;/code&gt; tag refers to the logger that is currently using that appender. If you have a different logger use the &lt;code&gt;logger-ref&lt;/code&gt; tag to refer to it instead.

&lt;pre class="brush:xml; gutter:false;"&gt;
  &amp;lt;appender name="file" class="org.apache.log4j.DailyRollingFileAppender"&amp;gt;
  &amp;lt;errorHandler class="org.apache.log4j.varia.FallbackErrorHandler"&amp;gt;
       &amp;lt;root-ref/&amp;gt;
       &amp;lt;appender-ref ref="console"/&amp;gt;
  &amp;lt;/errorHandler&amp;gt;
    &amp;lt;param name="File" value="C:/temp/test.log"/&amp;gt;
    &amp;lt;layout class="org.apache.log4j.PatternLayout"&amp;gt;
      &amp;lt;param name="ConversionPattern" value="%d %-5p %30.30c - %m%n"/&amp;gt;
    &amp;lt;/layout&amp;gt;
  &amp;lt;/appender&amp;gt;
&lt;/pre&gt;

&lt;b&gt;&lt;font color="#000099"&gt;3. Trying it out:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
To test this works, make your log file read-only, or change the path of the file to one which doesn't exist. When you run your application, you will see log4j print an error to stderr, and start logging to console, instead of file. If you turn log4j debug on you will see the message: "FB: INITIATING FALLBACK PROCEDURE." before console logging begins.
&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;The complete log4j.xml configuration:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
Here is my complete config file. (I tried setting up a log4j.properties file, but ran into problems and wasn't able to.)
&lt;pre class="brush:xml; gutter:false;"&gt;
&amp;lt;?xml version="1.0" encoding="UTF-8" ?&amp;gt;
&amp;lt;!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"&amp;gt;
&amp;lt;log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"&amp;gt;
    &amp;lt;appender name="console" class="org.apache.log4j.ConsoleAppender"&amp;gt;
        &amp;lt;param name="Target" value="System.out" /&amp;gt;
        &amp;lt;layout class="org.apache.log4j.PatternLayout"&amp;gt;
            &amp;lt;param name="ConversionPattern" value="%d %-5p %30.30c - %m%n" /&amp;gt;
        &amp;lt;/layout&amp;gt;
    &amp;lt;/appender&amp;gt;
    &amp;lt;appender name="file" class="org.apache.log4j.DailyRollingFileAppender"&amp;gt;
        &amp;lt;errorHandler class="org.apache.log4j.varia.FallbackErrorHandler"&amp;gt;
            &amp;lt;root-ref /&amp;gt;
            &amp;lt;appender-ref ref="console" /&amp;gt;
        &amp;lt;/errorHandler&amp;gt;
        &amp;lt;param name="File" value="C:/temp/test.log" /&amp;gt;
        &amp;lt;layout class="org.apache.log4j.PatternLayout"&amp;gt;
            &amp;lt;param name="ConversionPattern" value="%d %-5p %30.30c - %m%n" /&amp;gt;
        &amp;lt;/layout&amp;gt;
    &amp;lt;/appender&amp;gt;
    &amp;lt;root&amp;gt;
        &amp;lt;level value="INFO" /&amp;gt;
        &amp;lt;appender-ref ref="file" /&amp;gt;
    &amp;lt;/root&amp;gt;
&amp;lt;/log4j:configuration&amp;gt;
&lt;/pre&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-606507096153480979?l=fahdshariff.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/606507096153480979/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2009/10/using-log4js-fallbackerrorhandler.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/606507096153480979?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/606507096153480979?v=2" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/2009/10/using-log4js-fallbackerrorhandler.html" title="Using log4j's FallbackErrorHandler" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11444574926882287120" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;Ck4EQn07fyp7ImA9WxNXE0w.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-8180830929323792945</id><published>2009-09-30T12:25:00.000+01:00</published><updated>2009-09-30T12:41:43.307+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-30T12:41:43.307+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="syntaxhighlighter" /><category scheme="http://www.blogger.com/atom/ns#" term="html" /><category scheme="http://www.blogger.com/atom/ns#" term="webdesign" /><title>Upgrading to SyntaxHighlighter 2.0</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
I have now upgraded this blog to use &lt;a href="http://alexgorbatchev.com/wiki/SyntaxHighlighter"&gt;SyntaxHighlighter 2.0&lt;/a&gt;. It was very easy. You don't need to make changes to any of your old posts, because this release is backwards compatible.
&lt;p/&gt;
Another thing to note is that I had to make a change to &lt;code&gt;shBrushBash.js&lt;/code&gt; as it wasn't formatting file redirect characters (&amp;gt;, &amp;lt;) correctly.
&lt;p/&gt;
This is how you can upgrade too:
&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;1. Download SyntaxHighlighter v2.0&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
You can download it &lt;a href="http://alexgorbatchev.com/wiki/SyntaxHighlighter:Download"&gt;here&lt;/a&gt;. &lt;br/&gt;
If you don't have a place to upload, you can link to my free hosted version &lt;a href="http://sites.google.com/site/fahdshariff/syntaxhighlighter"&gt;here&lt;/a&gt;.

&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;2. Link to CSS and Javascript&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
Open your webpage's HTML file and add links to the SyntaxHighlighter's CSS and JavaScript files. For optimal results, place these lines at the very end of your page, just before the closing body tag.

&lt;pre class="brush:xml; gutter:false"&gt;
&amp;lt;link type="text/css" rel="stylesheet" href="http://sites.google.com/site/fahdshariff/syntaxhighlighter/styles/shCore.css"&amp;gt;&amp;lt;/link&amp;gt;
&amp;lt;link type="text/css" rel="stylesheet" href="http://sites.google.com/site/fahdshariff/syntaxhighlighter/styles/shThemeDefault.css"&amp;gt;&amp;lt;/link&amp;gt;
&amp;lt;script type="text/javascript" src="http://sites.google.com/site/fahdshariff/syntaxhighlighter/scripts/shCore.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type="text/javascript" src="http://sites.google.com/site/fahdshariff/syntaxhighlighter/scripts/shLegacy.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type="text/javascript" src="http://sites.google.com/site/fahdshariff/syntaxhighlighter/scripts/shBrushBash.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type="text/javascript" src="http://sites.google.com/site/fahdshariff/syntaxhighlighter/scripts/shBrushJava.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type="text/javascript" src="http://sites.google.com/site/fahdshariff/syntaxhighlighter/scripts/shBrushXml.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type="text/javascript" src="http://sites.google.com/site/fahdshariff/syntaxhighlighter/scripts/shBrushSql.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type="text/javascript"&amp;gt;
    SyntaxHighlighter.config.bloggerMode = true;
    SyntaxHighlighter.config.clipboardSwf = 'http://sites.google.com/site/fahdshariff/syntaxhighlighter/scripts/clipboard.swf';
    SyntaxHighlighter.all();
    dp.SyntaxHighlighter.HighlightAll('code');
&amp;lt;/script&amp;gt;
&lt;/pre&gt;
It is not necessary to add the js files for all languages - just for the ones you will be using.
&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;3. Add Code&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
Now add the code you wish to highlight in your webpage, surrounded by the &lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt; tag. Set the &lt;code&gt;class&lt;/code&gt; attribute to the language alias e.g. &lt;code&gt;brush:java&lt;/code&gt;:

&lt;pre class="brush:xml; gutter:false"&gt;
&amp;lt;pre class="brush: java; gutter: false;"&amp;gt;
public void printHello(){
    System.out.println("Hello World");
}
&amp;lt;/pre&amp;gt;
&lt;/pre&gt;

&lt;b&gt;&lt;font color="#000099"&gt;4. View Page&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
View the webpage in your browser and you should see your syntax highlighted code snippet.

&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Links:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
&lt;a href="http://alexgorbatchev.com/wiki/SyntaxHighlighter"&gt;SyntaxHighlighter Home Page&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://fahdshariff.blogspot.com/2008/07/syntax-highlighting-code-in-webpages.html"&gt;Syntax Highlighting Code in Webpages (with SyntaxHighlighter 1.5)&lt;/a&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-8180830929323792945?l=fahdshariff.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/8180830929323792945/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2009/09/upgrading-to-syntaxhighlighter-20.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/8180830929323792945?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/8180830929323792945?v=2" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/2009/09/upgrading-to-syntaxhighlighter-20.html" title="Upgrading to SyntaxHighlighter 2.0" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11444574926882287120" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;C08HQHw6eSp7ImA9WxNXE00.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-1600918012438811750</id><published>2009-09-30T08:42:00.002+01:00</published><updated>2009-09-30T10:10:31.211+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-30T10:10:31.211+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="wrapper" /><category scheme="http://www.blogger.com/atom/ns#" term="UNIX" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="scripting" /><title>Unix Wrapper Script for Java Applications</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
All of my Java applications are deployed onto a Unix (Linux or Solaris) environment and so I need to have a unix wrapper shell script in order to start and stop them. I looked at &lt;a href="http://wrapper.tanukisoftware.org"&gt;Java Service Wrapper&lt;/a&gt; but I wanted something simpler. So I wrote my own little wrapper, based on JSW.
&lt;p/&gt;

The wrapper allows you to invoke the following set of commands on your application:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&lt;b&gt;start&lt;/b&gt;&lt;/code&gt;: Starts up the application and writes its pid to a pid file. it also writes the hostname to the pid file. This is important, in case you try to run commands on the application on a different server. After starting, it waits a number of seconds and then checks to see if the application is still running.&lt;/li&gt;

&lt;li&gt;&lt;code&gt;&lt;b&gt;stop&lt;/b&gt;&lt;/code&gt;: Stops the application using the &lt;code&gt;kill&lt;/code&gt; command. If it has not died within 10 seconds, it executes the harder &lt;code&gt;kill -9&lt;/code&gt; command.&lt;/li&gt;

&lt;li&gt;&lt;code&gt;&lt;b&gt;restart&lt;/b&gt;&lt;/code&gt;: Restarts the application by calling &lt;code&gt;stop&lt;/code&gt; and then &lt;code&gt;start&lt;/code&gt;.&lt;/li&gt;

&lt;li&gt;&lt;code&gt;&lt;b&gt;status&lt;/b&gt;&lt;/code&gt;:Reads the pid file and invokes &lt;code&gt;kill -0&lt;/code&gt; on the pid to see if the process is alive. If the process is not alive, an email alert is generated, if the &lt;code&gt;$EMAIL&lt;/code&gt; variable has been set.&lt;/li&gt;

&lt;li&gt;&lt;code&gt;&lt;b&gt;dump&lt;/b&gt;&lt;/code&gt;: Generates a full Java thread dump by invoking &lt;code&gt;kill -3&lt;/code&gt; on the pid&lt;/li&gt;

&lt;li&gt;&lt;code&gt;&lt;b&gt;purge&lt;/b&gt;&lt;/code&gt;: Purges log files&lt;/li&gt;
&lt;/ul&gt;

Here is the wrapper script (&lt;code&gt;bin/console.ksh&lt;/code&gt;):

&lt;pre class="brush:bash; gutter:false;"&gt;
#! /bin/ksh
# A generic wrapper script to stop and start components.
# Usage: console.ksh { start | stop | restart | status | purge | dump }
#

APP_NAME="APP"
APP_LONG_NAME="MyApplication"

#the location of the pid files.
PIDDIR="../pid"
PIDFILE="$PIDDIR/$APP_NAME.pid"
TIMESTAMP=$( date +%Y%m%d_%H%M%S )

#number of seconds to wait after starting up.
WAIT_AFTER_STARTUP=2

#the location of the log files
LOG_DIR="../log"
STDOUT="$LOG_DIR/${APP_NAME}.stdout.log"

PURGE_EXPRESSION="-mtime +2"

VMARGS="-Xms250M -Xmx3000M -verbose:gc"
MAINCLASS="com.blogspot.fahdshariff.MyApplication"
ARGS="arg1 arg2"

if [ -z ${JAVA_HOME} ]
then
 echo JAVA_HOME has not been set.
 exit 1
fi

START_COMMAND="${JAVA_HOME}/bin/java $VMARGS $MAINCLASS $ARGS"

#-----------------------------------------------------------------------------
# Do not modify anything beyond this point
#-----------------------------------------------------------------------------

getpid() {
  pid=""
  if [ -f "$PIDFILE" ]
  then
    if [ -r "$PIDFILE" ]
    then
      pid=`cat "$PIDFILE"|cut -d: -f1`
      host=`cat "$PIDFILE"|cut -d: -f2`
      currhost=`hostname`
      if [ "$host" != "$currhost" ]
      then
       echo "You are on the wrong host. $APP_LONG_NAME runs on $host."
       exit 1
      fi

      if [ "X$pid" != "X" ]
      then
       kill -0 $pid &gt; /dev/null 2&gt;&amp;1
  if [ $? -ne 0 ]
  then
   # Process doesn't exist, so remove pidfile
   rm -f "$PIDFILE"
            echo "Removed stale pid file: $PIDFILE"
   pid=""
  fi
      fi
    else
      echo "Cannot read $PIDFILE."
      exit 1
    fi
  fi
}

#tests if the pid is alive
testpid() {
  kill -0 $pid &gt; /dev/null 2&gt;&amp;1
  if [ $? -ne 0 ]
  then
   # Process is gone so remove the pid file.
 rm -f "$PIDFILE"
 pid=""
  fi
}

start() {
  echo "Starting $APP_LONG_NAME..."
  getpid
  if [ "X$pid" = "X" ]
  then
    if [ -s $STDOUT ]
    then
     #backup current file
     mv $STDOUT $STDOUT.sav.${TIMESTAMP}
    fi
    echo CLASSPATH is $CLASSPATH &gt; $STDOUT
    echo ${START_COMMAND} &gt;&gt; $STDOUT
    nohup ${START_COMMAND} &gt;&gt; $STDOUT 2&gt;&amp;1 &amp;
    echo $!:`hostname` &gt; $PIDFILE
  else
    echo "$APP_LONG_NAME is already running."
    exit 1
  fi

  # Sleep for a few seconds to allow for intialization if required
  # then test to make sure we're still running.
  i=0
  while [ $i -lt $WAIT_AFTER_STARTUP ]
  do
    sleep 1
    i=`expr $i + 1`
  done
  if [ $WAIT_AFTER_STARTUP -gt 0 ]
  then
    getpid
    if [ "X$pid" = "X" ]
    then
      echo "WARNING: $APP_LONG_NAME may have failed to start."
      exit 1
    else
      echo "running ($pid)."
    fi
  else
    echo ""
  fi
}


stopit() {

  echo "Stopping $APP_LONG_NAME..."
  getpid
  if [ "X$pid" = "X" ]
  then
    echo "$APP_LONG_NAME was not running."
  else
    # Running so try to stop it.
    kill $pid
    if [ $? -ne 0 ]
    then
      echo "Unable to stop $APP_LONG_NAME."
      exit 1
    fi

    #  If it has not stopped in 10 tries, forcibly kill it
    savepid=$pid
    CNT=0
    TOTCNT=0
    while [ "X$pid" != "X" ]
    do
      # Show a waiting message every 5 seconds.
      if [ "$CNT" -lt "5" ]
      then
        CNT=`expr $CNT + 1`
      else
        echo "Waiting for $APP_LONG_NAME to exit..."
        CNT=0
      fi

      if [ $TOTCNT -gt 11 ]
      then
       echo "Killing by force (kill -9)"
       kill -9 $pid
      fi

      TOTCNT=`expr $TOTCNT + 1`
      sleep 1

      testpid
    done

    pid=$savepid
    testpid
    if [ "X$pid" != "X" ]
    then
      echo "Failed to stop $APP_LONG_NAME."
      exit 1
    else
      echo "Stopped $APP_LONG_NAME."
    fi
  fi
}

purge() {
  pcmd="find $LOG_DIR -follow -type f $PURGE_EXPRESSION -print -exec rm -f {} +"
  echo "Running purge: $pcmd"
  $pcmd
}

alert() {
  if [ "X$EMAIL" != "X" ]
  then
   echo "$APP_LONG_NAME is not running on `hostname`. Please check and restart." \
   | mailx -s "`hostname`: $APP_LONG_NAME is not running" "$EMAIL"
   echo "Sent alert to $EMAIL"
  fi
}

status() {
  getpid
  if [ "X$pid" = "X" ]
  then
    echo "$APP_LONG_NAME is not running."
    alert
    exit 1
  else
    echo "$APP_LONG_NAME is running (PID:$pid)."
    exit 0
  fi
}

dump() {
  echo "Dumping $APP_LONG_NAME..."
  getpid
  if [ "X$pid" = "X" ]
  then
    echo "$APP_LONG_NAME is not running."
  else
    kill -3 $pid

    if [ $? -ne 0 ]
    then
      echo "Failed to dump $APP_LONG_NAME."
      exit 1
    else
      echo "Dumped $APP_LONG_NAME."
    fi
  fi
}

####################

case "$1" in

  'start')
    start
    ;;

  'stop')
    stopit
    ;;

  'restart')
    stopit
    start
    ;;

  'status')
    status
    ;;

  'dump')
    dump
    ;;

  'purge')
    purge
    ;;

  *)
    echo "Usage: $0 { start | stop | restart | status | dump | purge }"
    exit 1
    ;;
esac

exit 0
&lt;/pre&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-1600918012438811750?l=fahdshariff.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/1600918012438811750/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2009/09/unix-wrapper-script-for-java.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/1600918012438811750?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/1600918012438811750?v=2" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/2009/09/unix-wrapper-script-for-java.html" title="Unix Wrapper Script for Java Applications" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11444574926882287120" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;C0YARXY9eCp7ImA9WxNXEkw.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-8922627437038099737</id><published>2009-09-29T08:59:00.000+01:00</published><updated>2009-09-29T08:59:04.860+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-29T08:59:04.860+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="UNIX" /><category scheme="http://www.blogger.com/atom/ns#" term="bash" /><category scheme="http://www.blogger.com/atom/ns#" term="scripting" /><title>Bash: Convert String to Array</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;

This is how you can convert a string into an array:

&lt;pre name="code" class="java:nogutter:nocontrols"&gt;
s="124890"
for i in $(seq 0 $((${#s}-1)))
do
     arr[$i]=${s:$i:1}
done
&lt;/pre&gt;

&lt;code&gt;${#s}&lt;/code&gt; refers to the length of the string s, which in this case is 6.&lt;br/&gt;
&lt;code&gt;${s:$i:1}&lt;/code&gt; returns a substring of s, starting from &lt;code&gt;$i&lt;/code&gt;, of length 1.
&lt;p/&gt;
The &lt;code&gt;seq&lt;/code&gt; command is a new one for me. Unfortunately, it doesn't seem to be available on Solaris, only Linux. From the &lt;code&gt;man&lt;/code&gt; pages:
&lt;pre&gt;
NAME
       seq - print a sequence of numbers

SYNOPSIS
       seq [OPTION]... LAST
       seq [OPTION]... FIRST LAST
       seq [OPTION]... FIRST INCREMENT LAST
&lt;/pre&gt;

To see how you can convert a string of digits to an array in other languages, read this
&lt;a href="http://stackoverflow.com/questions/166899/language-showdown-convert-string-of-digits-to-array-of-integers"/&gt;stackoverflow question&lt;/a&gt;.


&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-8922627437038099737?l=fahdshariff.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/8922627437038099737/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2009/09/bash-convert-string-to-array.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/8922627437038099737?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/8922627437038099737?v=2" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/2009/09/bash-convert-string-to-array.html" title="Bash: Convert String to Array" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11444574926882287120" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DEACSHczcSp7ImA9WxNXEU4.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-7442915767829803113</id><published>2009-09-28T12:19:00.000+01:00</published><updated>2009-09-28T12:19:29.989+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-28T12:19:29.989+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>Double Brace Initialisation</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
"Double Brace Initialisation" is one of the lesser known features in Java. It can be useful for initialising collections that have to be passed to other methods.
&lt;p/&gt;
For example, without double-brace initialisation:
&lt;pre name="code" class="java:nogutter:nocontrols"&gt;
Map&amp;lt;String,String&amp;gt; map = new HashMap &amp;lt;String,String&amp;gt;();
map.put("key","value");
map.put("key2","value2");
printMap(map);
&lt;/pre&gt;

With double-brace initialisation:

&lt;pre name="code" class="java:nogutter:nocontrols"&gt;
printMap(new HashMap &amp;lt;String,String&amp;gt;(){{
            put("key","value");
            put("key2","value2");
        }});
&lt;/pre&gt;

The first brace creates a new AnonymousInnerClass, the second declares an instance initializer block that is run when the anonymous inner class is instantiated. This only works only for non-final classes because it creates an anonymous subclass.

&lt;p/&gt;
Don't go too overboard with this because it creates a new anonymous inner class just for making a single object which might not be very efficient! It will also create an additional class file on disk. 

&lt;p/&gt;
Another example:

&lt;pre name="code" class="java:nogutter:nocontrols"&gt;
//double-brace initialisation
List&amp;lt;String&amp;gt; list = new ArrayList&amp;lt;String&amp;gt;(){{
   add("apple");
   add("banana");
}};

//better alternative
List&amp;lt;String&amp;gt; list2 = Arrays.asList("apple","banana");
&lt;/pre&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-7442915767829803113?l=fahdshariff.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/7442915767829803113/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2009/09/double-brace-initialisation.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/7442915767829803113?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/7442915767829803113?v=2" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/2009/09/double-brace-initialisation.html" title="Double Brace Initialisation" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11444574926882287120" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DUcBQH05fip7ImA9WxNSFUg.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-1983031898770909519</id><published>2009-08-29T15:44:00.000+01:00</published><updated>2009-08-29T15:44:11.326+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-29T15:44:11.326+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="eclipse" /><title>Speed up Eclipse</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
I've just noticed a big performance improvement in Eclipse 3.5 (Galileo), just by launching it with the latest JRE (1.6.0_16) and unlocking the new G1 garbage collector. My startup time has reduced from about 30 secs to 4-5 secs and the interface is snappier.
&lt;p/&gt;
Here is my &lt;code&gt;eclipse.ini&lt;/code&gt;:

&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
-startup
plugins/org.eclipse.equinox.launcher_1.0.200.v20090520.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_1.0.200.v20090519
-product
org.eclipse.epp.package.java.product
-data
c:\eclipse
-showlocation
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
384m
-vm
C:\program files\Java\jdk1.6.0_16\jre\bin\client\jvm.dll
-vmargs
-Dosgi.requiredJavaVersion=1.5
-Xms128m
-Xmx384m
-Xss4m
-XX:PermSize=128m
-XX:MaxPermSize=128m
-XX:CompileThreshold=5
-XX:MaxGCPauseMillis=10
-XX:MaxHeapFreeRatio=70
-XX:+UnlockExperimentalVMOptions
-XX:+UseG1GC
-XX:+UseFastAccessorMethods
-XX:+AggressiveOpts
-Dcom.sun.management.jmxremote
&lt;/pre&gt;
Let me know if there are any other improvements I can make!
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-1983031898770909519?l=fahdshariff.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/1983031898770909519/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2009/08/speed-up-eclipse.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/1983031898770909519?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/1983031898770909519?v=2" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/2009/08/speed-up-eclipse.html" title="Speed up Eclipse" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11444574926882287120" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;D0MGSXs6eCp7ImA9WxNTFkw.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-2043677667393140756</id><published>2009-08-18T18:10:00.000+01:00</published><updated>2009-08-18T18:10:28.510+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-18T18:10:28.510+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="UNIX" /><category scheme="http://www.blogger.com/atom/ns#" term="crontab" /><title>Cron Jobs Not Launching</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
We had an issue recently with cron jobs not firing on our Solaris 10 server. We finally tracked it down to cron not being initialised when the server rebooted. The error was in a file called &lt;code&gt;/var/svc/log/system-cron:default.log&lt;/code&gt; and indicated that it couldn't find the user. Possibly due to NFS not being mounted.
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;b&gt;sharfah@starship:~&amp;gt;&lt;/b&gt; tail -10 /var/svc/log/system-cron:default.log
&lt;font color="green"&gt;[ Aug 16 00:01:25 Stopping because service disabled. ]
[ Aug 16 00:01:25 Executing stop method (:kill) ]
[ Aug 16 00:07:27 Enabled. ]
[ Aug 16 00:07:28 Executing start method ("/lib/svc/method/svc-cron") ]
[ Aug 16 00:07:28 Method "start" exited with status 0 ]
! No such user as sharfah - cron entries not created Sun Aug 16 00:07:28 2009
&lt;/font&gt;&lt;/pre&gt;
We then got the Unix SAs to restart &lt;code&gt;svc:/system/cron:default&lt;/code&gt;:
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;b&gt;sharfah@starship:~&amp;gt;&lt;/b&gt; tail -10 /var/svc/log/system-cron:default.log
&lt;font color="green"&gt;[ Aug 18 17:25:19 Stopping because service restarting. ]
[ Aug 18 17:25:19 Executing stop method (:kill) ]
[ Aug 18 17:25:20 Executing start method ("/lib/svc/method/svc-cron") ]
[ Aug 18 17:25:20 Method "start" exited with status 0 ]
&lt;/font&gt;&lt;/pre&gt;
Another way to fix this issue, is to edit and resave &lt;code&gt;crontab&lt;/code&gt;.
&lt;p/&gt;
For debugging cron issues, a useful tip is to look at &lt;code&gt;/var/mail/&lt;i&gt;user&lt;/i&gt;&lt;/code&gt; which will contain any stdout or errors from your cron jobs.
&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Related post:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
&lt;a href="http://fahdshariff.blogspot.com/2009/05/percent-sign-in-crontab.html"&gt;Percent Sign in Crontab&lt;/a&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-2043677667393140756?l=fahdshariff.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/2043677667393140756/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2009/08/cron-jobs-not-launching.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/2043677667393140756?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/2043677667393140756?v=2" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/2009/08/cron-jobs-not-launching.html" title="Cron Jobs Not Launching" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11444574926882287120" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;A0IHSHs6eSp7ImA9WxNTFU0.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-1442485706235035926</id><published>2009-08-17T12:45:00.000+01:00</published><updated>2009-08-17T12:45:39.511+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-17T12:45:39.511+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><title>Retrying Operations in Java</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
There are many cases in which you may wish to retry an operation a certain number of times. Examples are database failures, network communication failures or file IO problems.
&lt;p/&gt;

&lt;b&gt;&lt;font color="#000099"&gt;Approach 1&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
This is the traditional approach and involves a counter and a loop.

&lt;pre name="code" class="java:nogutter:nocontrols"&gt;
final int numberOfRetries = 5 ;
final long timeToWait = 1000 ;

for (int i=0; i&amp;lt;numberOfRetries; i++) {
 //perform the operation
 try {
  Naming.lookup("rmi://localhost:2106/MyApp");
  break;
 }
 catch (Exception e) {
  logger.error("Retrying...",e);
  try {
   Thread.sleep(timeToWait);
  }
  catch (InterruptedException i) {
  }
 }
}
&lt;/pre&gt;

&lt;b&gt;&lt;font color="#000099"&gt;Approach 2&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
In this approach, we hide the retry counter in a separate class called &lt;code&gt;RetryStrategy&lt;/code&gt; and call it like this:

&lt;pre name="code" class="java:nogutter:nocontrols"&gt;
public class RetryStrategy
{
 public static final int DEFAULT_NUMBER_OF_RETRIES = 5;
 public static final long DEFAULT_WAIT_TIME = 1000;

 private int numberOfRetries; //total number of tries
 private int numberOfTriesLeft; //number left
 private long timeToWait; //wait interval

 public RetryStrategy()
 {
  this(DEFAULT_NUMBER_OF_RETRIES, DEFAULT_WAIT_TIME);
 }

 public RetryStrategy(int numberOfRetries, long timeToWait)
 {
  this.numberOfRetries = numberOfRetries;
  numberOfTriesLeft = numberOfRetries;
  this.timeToWait = timeToWait;
 }

 /**
  * @return true if there are tries left
  */
 public boolean shouldRetry()
 {
  return numberOfTriesLeft &amp;gt; 0;
 }

 /**
  * This method should be called if a try fails.
  *
  * @throws RetryException if there are no more tries left
  */
 public void errorOccured() throws RetryException
 {
  numberOfTriesLeft --;
  if (!shouldRetry())
  {
   throw new RetryException(numberOfRetries +
     " attempts to retry failed at " + getTimeToWait() +
     "ms interval");
  }
  waitUntilNextTry();
 }

 /**
  * @return time period between retries
  */
 public long getTimeToWait()
 {
  return timeToWait ;
 }

 /**
  * Sleeps for the duration of the defined interval
  */
 private void waitUntilNextTry()
 {
  try
  {
   Thread.sleep(getTimeToWait());
  }
  catch (InterruptedException ignored) {}
 }

 public static void main(String[] args) {
  RetryStrategy retry = new RetryStrategy();
  while (retry.shouldRetry()) {
   try {
    Naming.lookup("rmi://localhost:2106/MyApp");
    break;
   }
   catch (Exception e) {
    try {
     retry.errorOccured();
    }
    catch (RetryException e1) {
     e.printStackTrace();
    }
   }
  }
 }
}
&lt;/pre&gt;

&lt;b&gt;&lt;font color="#000099"&gt;Approach 3&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
Approach 2, although cleaner, hasn't really reduced the number of lines of code we have to write. In the next approach, we hide the retry loop and all logic in a separate class called &lt;code&gt;RetriableTask&lt;/code&gt;. We make the operation that we are going to retry &lt;code&gt;Callable&lt;/code&gt; and wrap it in a &lt;code&gt;RetriableTask&lt;/code&gt; which then handles all the retrying for us, behind-the-scenes:

&lt;pre name="code" class="java:nogutter:nocontrols"&gt;
public class RetriableTask&amp;lt;T&amp;gt; implements Callable&amp;lt;T&amp;gt; {

 private Callable&amp;lt;T&amp;gt; task;
 public static final int DEFAULT_NUMBER_OF_RETRIES = 5;
 public static final long DEFAULT_WAIT_TIME = 1000;

 private int numberOfRetries; // total number of tries
 private int numberOfTriesLeft; // number left
 private long timeToWait; // wait interval

 public RetriableTask(Callable&amp;lt;T&amp;gt; task) {
  this(DEFAULT_NUMBER_OF_RETRIES, DEFAULT_WAIT_TIME, task);
 }

 public RetriableTask(int numberOfRetries, long timeToWait,
                      Callable&amp;lt;T&amp;gt; task) {
  this.numberOfRetries = numberOfRetries;
  numberOfTriesLeft = numberOfRetries;
  this.timeToWait = timeToWait;
  this.task = task;
 }

 public T call() throws Exception {
  while (true) {
   try {
    return task.call();
   }
   catch (InterruptedException e) {
    throw e;
   }
   catch (CancellationException e) {
    throw e;
   }
   catch (Exception e) {
    numberOfTriesLeft--;
    if (numberOfTriesLeft == 0) {
     throw new RetryException(numberOfRetries +
     " attempts to retry failed at " + timeToWait +
     "ms interval", e);
    }
    Thread.sleep(timeToWait);
   }
  }
 }

 public static void main(String[] args) {
  Callable&amp;lt;Remote&amp;gt; task = new Callable&amp;lt;Remote&amp;gt;() {
   public Remote call() throws Exception {
    String url="rmi://localhost:2106/MyApp";
    return (Remote) Naming.lookup(url);
   }
  };

  RetriableTask&amp;lt;Remote&amp;gt; r = new RetriableTask&amp;lt;Remote&amp;gt;(task);
  try {
   r.call();
  }
  catch (Exception e) {
   e.printStackTrace();
  }
 }
}
&lt;/pre&gt;

&lt;b&gt;&lt;font color="#000099"&gt;References:&lt;/font&gt;&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://onjava.com/pub/a/onjava/2001/10/17/rmi.html?page=3"&gt;Learning Command Objects and RMI [onjava]&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://biotext.org.uk/retriabletask-a-generic-wrapper-for-retrying-operations-in-java/"&gt;RetriableTask - a generic wrapper for retrying operations in Java&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-1442485706235035926?l=fahdshariff.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/1442485706235035926/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2009/08/retrying-operations-in-java.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/1442485706235035926?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/1442485706235035926?v=2" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/2009/08/retrying-operations-in-java.html" title="Retrying Operations in Java" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11444574926882287120" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;A0MBQng-eyp7ImA9WxJaFE0.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-4799159947665394877</id><published>2009-08-04T19:10:00.000+01:00</published><updated>2009-08-04T19:10:53.653+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-04T19:10:53.653+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="CVS" /><category scheme="http://www.blogger.com/atom/ns#" term="CollabNet" /><category scheme="http://www.blogger.com/atom/ns#" term="SSH" /><title>Setting up Tortoise CVS with CollabNet</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
We recently moved from Sourceforge to CollabNet and had to make changes to our CVS client setup. Sourceforge uses "pserver", whereas Collabnet uses "ext ssh". This is how you can get Tortoise CVS to connect to CollabNet, without prompting you for passwords every time.
&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;1. Create a pair of public/private keys&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
You can create a pair of keys using PuTTY Key Generator (PUTTYGEN.EXE). Simply press the Generate button and move your mouse to generate randomness. This will create a public key for pasting into an authorized_keys file. Press the Save public key and Save private key buttons to save the keys as files. I have saved mine as:
&lt;ul&gt;
&lt;li&gt;C:\Documents and Settings\[xpid]\ssh\id_dsa (private) &lt;/li&gt;
&lt;li&gt;C:\Documents and Settings\[xpid]\ssh\id_dsa.pub (public)&lt;/li&gt;
&lt;/ul&gt;
Alternatively, you can use the UNIX utility "ssh-keygen", as explained in one of my previous posts &lt;a href="http://fahdshariff.blogspot.com/2008/07/ssh-without-password.html"&gt;here&lt;/a&gt;.
&lt;p/&gt;

&lt;b&gt;&lt;font color="#000099"&gt;2. Store your public key on CollabNet&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
&lt;ul&gt;
&lt;li&gt;Log onto CollabNet&lt;/li&gt;
&lt;li&gt;Click on My Workspace&lt;/li&gt;
&lt;li&gt;Click on Authorization Keys&lt;/li&gt;
&lt;li&gt;Paste the public key, generated in Step 1, into the Authorized Keys text area and press Update&lt;/li&gt;
&lt;/ul&gt;

&lt;b&gt;&lt;font color="#000099"&gt;3. Update Tortoise SSH Settings&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
&lt;ul&gt;
&lt;li&gt;Open TortoiseCVS Preferences&lt;/li&gt;
&lt;li&gt;Go to the Tools tab&lt;/li&gt;
&lt;li&gt;Add your private key to your SSH parameters, so that it becomes:&lt;/li&gt;&lt;/ul&gt;
&lt;pre&gt;-i "C:\Documents and Settings\[xpid]\ssh\id_dsa" -l "%u" "%h"&lt;/pre&gt;


Now, whenever you perform a CVS operation through Tortoise, it will not prompt you for a password.
&lt;p/&gt;
Your CVSROOT should look something like this:
&lt;pre&gt;:ext:fahd_shariff@cvs-collabnet.server.com:/cvsroot/module&lt;/pre&gt;

&lt;b&gt;&lt;font color="#000099"&gt;References:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
&lt;a href="http://www.tortoisecvs.org/faq.shtml#sshkeys"&gt;Tortoise FAQs&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://help.collab.net/index.jsp?topic=/csfe500/tasks/code-storingsshkeys.html"&gt;CollabNet Help&lt;/a&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-4799159947665394877?l=fahdshariff.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/4799159947665394877/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2009/08/setting-up-tortoise-cvs-with-collabnet.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/4799159947665394877?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/4799159947665394877?v=2" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/2009/08/setting-up-tortoise-cvs-with-collabnet.html" title="Setting up Tortoise CVS with CollabNet" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11444574926882287120" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DkEMQ3k8eip7ImA9WxJbF08.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-1961068502458252963</id><published>2009-07-27T20:58:00.000+01:00</published><updated>2009-07-27T20:58:02.772+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-27T20:58:02.772+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SSL" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="certificate" /><category scheme="http://www.blogger.com/atom/ns#" term="keytool" /><title>Howto: Import Certificates into a Keystore</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
One night, our Java application, which connects to a webservice, started failing with the following error:
&lt;pre&gt;
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at org.apache.axis.AxisFault.makeFault(AxisFault.java:101)
at org.apache.axis.transport.http.HTTPSender.invoke(HTTPSender.java:154)
at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
at org.apache.axis.client.AxisClient.invoke(AxisClient.java:165)
at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
at org.apache.axis.client.Call.invoke(Call.java:2767)
at org.apache.axis.client.Call.invoke(Call.java:2443)
at org.apache.axis.client.Call.invoke(Call.java:2366)
at org.apache.axis.client.Call.invoke(Call.java:1812)
&lt;/pre&gt;

This error meant that our application did not have a valid certificate, but since our application had been working fine for the past few months, the only plausible explanation was that the webservice that we were trying to connect to, had changed their certificate without telling us!
&lt;p/&gt;
I then had to go about getting hold of the new certificate and importing it into my truststore, in order to get my application up and running again. This is how:

&lt;p/&gt;&lt;b&gt;&lt;font color="#000099"&gt;1) Save the SSL Certificate to a File&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
In Firefox 3.5 (it's easier):
&lt;ul&gt;
&lt;li&gt;Open the webservice url&lt;/li&gt;
&lt;li&gt;Double-click the padlock icon (or right-click on page and select Page Info)&lt;/li&gt;
&lt;li&gt;Click on the Security tab (the padlock icon)&lt;/li&gt;
&lt;li&gt;Press View Certificate&lt;/li&gt;
&lt;li&gt;Click on the Details tab&lt;/li&gt;
&lt;li&gt;Press Export...&lt;/li&gt;
&lt;li&gt;Choose a file to save to - I like to save as type: X.509 Certification (DER)&lt;/li&gt;
&lt;/ul&gt;
In Internet Explorer (IE 8):
&lt;ul&gt;
&lt;li&gt;Open the webservice url&lt;/li&gt;
&lt;li&gt;Click the padlock icon and then on View Certificates&lt;/li&gt;
&lt;li&gt;Click on Install Certificate, click Next&lt;/li&gt;
&lt;li&gt;Choose Place all certificates in the following store and Browse to Personal&lt;/li&gt;
&lt;li&gt;Click Next and run through the rest of the screens&lt;/li&gt;
&lt;li&gt;Go to Start &gt; Run &gt; certmgr.msc&lt;/li&gt;
&lt;li&gt;Select Personal&lt;/li&gt;
&lt;li&gt;Right click on certificate, go to All Tasks &gt; Export... &lt;/li&gt;
&lt;/ul&gt;
Once saved, you can view the certificate using Java Keytool as follows:
&lt;pre&gt;
keytool -printcert -file mycert.cer
&lt;/pre&gt;
&lt;p/&gt;&lt;b&gt;&lt;font color="#000099"&gt;2) Import Certificate to Keystore&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
Now that we have saved the website certificate to a local file, we can use Java Keytool to import it into our keystore using the following command:
&lt;pre&gt;
keytool -import -alias myalias -file mycert.cer \
        -keystore mytruststore
&lt;/pre&gt;
You can also display the contents of the keystore using the following command:
&lt;pre&gt;
keytool -list -v -keystore mytruststore
&lt;/pre&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-1961068502458252963?l=fahdshariff.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/1961068502458252963/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2009/07/howto-import-certificates-into-keystore.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/1961068502458252963?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/1961068502458252963?v=2" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/2009/07/howto-import-certificates-into-keystore.html" title="Howto: Import Certificates into a Keystore" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11444574926882287120" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CkUMSX45eyp7ImA9WxJUF0k.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-413319632068367689</id><published>2009-07-16T11:31:00.000+01:00</published><updated>2009-07-16T11:31:28.023+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-16T11:31:28.023+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="firefox" /><category scheme="http://www.blogger.com/atom/ns#" term="sso" /><title>Enabling Desktop SSO in Firefox</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
This is how you can configure Firefox to use Desktop Single Sign On (SSO) / Kerberos authentication:

&lt;ul&gt;
&lt;li&gt;Go to &lt;code&gt;about:config&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Change your preference &lt;code&gt;network.negotiate-auth.delegation-uris&lt;/li&gt; to the domain you want to authenticate against, for example ".domain.com".
&lt;li&gt;Change your preference &lt;code&gt;network.negotiate-auth.trusted-uris&lt;/li&gt; to the domain as above.
&lt;/ul&gt;

Now try going to a URL and you should be able to login automatically. This has been tried and tested with Firefox 3.5.

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-413319632068367689?l=fahdshariff.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/413319632068367689/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2009/07/enabling-desktop-sso-in-firefox.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/413319632068367689?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/413319632068367689?v=2" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/2009/07/enabling-desktop-sso-in-firefox.html" title="Enabling Desktop SSO in Firefox" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11444574926882287120" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total></entry><entry gd:etag="W/&quot;CU8NQnw_fCp7ImA9WxJVEEw.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-2443984500722454361</id><published>2009-06-26T11:58:00.000+01:00</published><updated>2009-06-26T11:58:13.244+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-26T11:58:13.244+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="UNIX" /><category scheme="http://www.blogger.com/atom/ns#" term="fibonacci" /><category scheme="http://www.blogger.com/atom/ns#" term="shell" /><category scheme="http://www.blogger.com/atom/ns#" term="scripting" /><title>Fibonacci Shell Script</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
Here is a quick unix shell script which prints out the Fibonacci sequence:
&lt;p/&gt;
0,1,1,2,3,5,8,13,21,34,55,89,144,...
&lt;p/&gt;
The first two Fibonacci numbers are 0 and 1, and each remaining number is the sum of the previous two.

&lt;pre name="code" class="java:nogutter:nocontrols"&gt;
#!/bin/sh
prev=0
next=1

echo $prev

while(true)
do
 echo $next

 #add the two numbers
 sum=$(($prev+$next))

 #swap
 prev=$next
 next=$sum
 sleep 1
done
&lt;/pre&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-2443984500722454361?l=fahdshariff.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/2443984500722454361/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2009/06/fibonacci-shell-script.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/2443984500722454361?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/2443984500722454361?v=2" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/2009/06/fibonacci-shell-script.html" title="Fibonacci Shell Script" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11444574926882287120" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;Dk8DQX4-eSp7ImA9WxJQGEo.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-9082344594143868050</id><published>2009-06-01T17:47:00.000+01:00</published><updated>2009-06-01T17:47:50.051+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-01T17:47:50.051+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="xpath" /><category scheme="http://www.blogger.com/atom/ns#" term="XML" /><title>Using XPath in Java</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
Given the following xml document:

&lt;pre name="code" class="xml:nogutter:nocontrols"&gt;
&amp;lt;hosts&amp;gt;
  &amp;lt;host name=&amp;quot;starship&amp;quot; port=&amp;quot;8080&amp;quot;/&amp;gt;
  &amp;lt;host name=&amp;quot;firefly&amp;quot; port=&amp;quot;8180&amp;quot;/&amp;gt;
&amp;lt;/hosts&amp;gt;
&lt;/pre&gt;

this is how you can use the &lt;code&gt;javax.xml.xpath&lt;/code&gt; library to run an XPath query in order to obtain a list of host names:

&lt;pre name="code" class="java:nogutter:nocontrols"&gt;
//create a document
DocumentBuilderFactory domFactory = 
                     DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse("file.xml");

//create the xpath expression
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
XPathExpression expr = xpath.compile("//host/@name");

//run the xpath query
Object result = expr.evaluate(doc, XPathConstants.NODESET);

//read results
NodeList nodes = (NodeList) result;
for (int i = 0; i &lt; nodes.getLength(); i++) {
    System.out.println(nodes.item(i).getNodeValue());
}&lt;/pre&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-9082344594143868050?l=fahdshariff.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/9082344594143868050/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2009/06/using-xpath-in-java.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/9082344594143868050?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/9082344594143868050?v=2" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/2009/06/using-xpath-in-java.html" title="Using XPath in Java" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11444574926882287120" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></entry><entry gd:etag="W/&quot;C08DRn07cCp7ImA9WxJRGU8.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-6530428793876358707</id><published>2009-05-21T16:58:00.001+01:00</published><updated>2009-05-21T17:04:37.308+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-21T17:04:37.308+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="UNIX" /><category scheme="http://www.blogger.com/atom/ns#" term="find" /><category scheme="http://www.blogger.com/atom/ns#" term="commands" /><title>find -exec vs xargs</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
If you want to execute a command on lots of files found by the &lt;code&gt;find&lt;/code&gt; command, there are a few different ways this can be achieved (some more efficient than others):
&lt;p/&gt;

&lt;b&gt;&lt;font color="#000099"&gt;-exec command {} \;&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
This is the traditional way. The end of the command must be punctuated by an escaped semicolon. The command argument {} is replaced by the current path name found by &lt;code&gt;find&lt;/code&gt;. Here is a simple command which echoes file paths.
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;b&gt;sharfah@starship:~&amp;gt;&lt;/b&gt; find . -type f -exec echo {} \;
&lt;font color="green"&gt;.
./1.txt
./2.txt&lt;/font&gt;&lt;/pre&gt;
This is very inefficient, because whenever &lt;code&gt;find&lt;/code&gt; finds a file, it forks a process for your command, waits for this child process to complete and then searches for the next file. In this example, you will get the following child processes: &lt;code&gt;echo .; echo ./1.txt; echo ./2.txt&lt;/code&gt;. So if there are 1000 files, there are 1000 child processes and &lt;code&gt;find&lt;/code&gt; waits.

&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;-exec command {} +&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
If you use a plus (+) instead of the escaped semicolon, the arguments will be grouped together before being passed to the command. The arguments must be at the end of the command.
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;b&gt;sharfah@starship:~&amp;gt;&lt;/b&gt; find . -type f -exec echo {} +
&lt;font color="green"&gt;. ./1.txt ./2.txt&lt;/font&gt;&lt;/pre&gt;
In this case, only one child process is created: &lt;code&gt;echo . ./1.txt ./2.txt&lt;/code&gt;, which is much more efficient, because it avoids a fork/exec for each single argument.

&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;xargs&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
This is similar to the approach above, in that files found are bundled up (usually in batches of about 20-50 names) and sent to the command as few times as possible. &lt;code&gt;find&lt;/code&gt; doesn't wait for your command to finish.
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;b&gt;sharfah@starship:~&amp;gt;&lt;/b&gt; find . -type f | xargs echo
&lt;font color="green"&gt;. ./1.txt ./2.txt&lt;/font&gt;&lt;/pre&gt;
This approach is efficient and works well as long as you do not have funny characters (e.g. spaces) in your filenames as they won't be escaped.
&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Performance Testing&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
So which one of the above approaches is fastest? I ran a test across a directory with 10,000 files out of which 5,600 matched my &lt;code&gt;find&lt;/code&gt; pattern. I ran the test 10 times, changing the order of the finds each time, but the results were always the same. &lt;code&gt;xargs&lt;/code&gt; and &lt;code&gt;+&lt;/code&gt; were very close, with &lt;code&gt;\;&lt;/code&gt; always finishing last. Here is one result:

&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
time find . -name "*20090430*" -exec touch {} +
&lt;font color="green"&gt;real    0m31.98s
user    0m0.06s
sys     0m0.49s
&lt;/font&gt;
time find . -name "*20090430*" | xargs touch
&lt;font color="green"&gt;real    1m8.81s
user    0m0.13s
sys     0m1.07s
&lt;/font&gt;
time find . -name "*20090430*" -exec touch {} \;
&lt;font color="green"&gt;real    1m42.53s
user    0m0.17s
sys     0m2.42s&lt;/font&gt;&lt;/pre&gt;
I'm going to be using the &lt;code&gt;-exec command {} +&lt;/code&gt; method, because it is faster and can handle my funny filenames.
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-6530428793876358707?l=fahdshariff.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/6530428793876358707/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2009/05/find-exec-vs-xargs.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/6530428793876358707?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/6530428793876358707?v=2" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/2009/05/find-exec-vs-xargs.html" title="find -exec vs xargs" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11444574926882287120" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;A08CQHgzeSp7ImA9WxJSGEs.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-6232925836142186796</id><published>2009-05-09T12:51:00.000+01:00</published><updated>2009-05-09T12:51:01.681+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-09T12:51:01.681+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="UNIX" /><category scheme="http://www.blogger.com/atom/ns#" term="Linux" /><category scheme="http://www.blogger.com/atom/ns#" term="crontab" /><title>Percent Sign in Crontab</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
From the man pages of crontab:

&lt;p style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;font color="green"&gt;The sixth field of a line in a crontab file is a string that is executed by the shell at the specified times. A percent character in this field (unless escaped by \) is translated to a &lt;b&gt;NEWLINE&lt;/b&gt; character.&lt;br/&gt;&lt;br/&gt;
Only the first line (up to a `%' or end of line) of the command field is executed by the shell. Other lines are made available to the command as standard input. Any blank line or line beginning with a `#' is a comment and is ignored.
&lt;/font&gt;&lt;/p&gt;

&lt;p/&gt;
This means that you need to escape any percent (%) characters. For example, I have a daily backup cron which writes the current crontab to a backup file every morning, and I have to escape the &lt;code&gt;date&lt;/code&gt; command, as shown below:

&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
01 07 * * * crontab -l &gt; /home/user/cron.`date +\%Y\%m\%d`
&lt;/pre&gt;

Also note, that cron isn't clever enough to expand the tilde (~) character, so always use the full path to your home directory.
&lt;p/&gt;

If you find that a cron hasn't fired, check your email in /var/mail/&lt;i&gt;user&lt;/i&gt;.

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-6232925836142186796?l=fahdshariff.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/6232925836142186796/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2009/05/percent-sign-in-crontab.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/6232925836142186796?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/6232925836142186796?v=2" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/2009/05/percent-sign-in-crontab.html" title="Percent Sign in Crontab" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11444574926882287120" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DkMFSHY-eSp7ImA9WxJSF0o.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-923749305507621976</id><published>2009-05-08T10:20:00.000+01:00</published><updated>2009-05-08T10:20:19.851+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-08T10:20:19.851+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="cpu" /><category scheme="http://www.blogger.com/atom/ns#" term="version" /><category scheme="http://www.blogger.com/atom/ns#" term="memory" /><category scheme="http://www.blogger.com/atom/ns#" term="commands" /><category scheme="http://www.blogger.com/atom/ns#" term="solaris" /><title>Solaris - CPU, Memory and Version</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
&lt;b&gt;&lt;font color="#000099"&gt;CPU Info:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
In order to find information about processors on Solaris, use the &lt;code&gt;psrinfo&lt;/code&gt; command:
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;b&gt;sharfah@starship:~&amp;gt;&lt;/b&gt; psrinfo -v
&lt;font color="green"&gt;Status of virtual processor 0 as of: 05/08/2009 09:53:17
  on-line since 05/03/2009 00:05:06.
  The i386 processor operates at 2612 MHz,
        and has an i387 compatible floating point processor.
Status of virtual processor 1 as of: 05/08/2009 09:53:17
  on-line since 05/03/2009 00:05:12.
  The i386 processor operates at 2612 MHz,
        and has an i387 compatible floating point processor.
Status of virtual processor 2 as of: 05/08/2009 09:53:17
  on-line since 05/03/2009 00:05:14.
  The i386 processor operates at 2612 MHz,
        and has an i387 compatible floating point processor.
Status of virtual processor 3 as of: 05/08/2009 09:53:17
  on-line since 05/03/2009 00:05:16.
  The i386 processor operates at 2612 MHz,
        and has an i387 compatible floating point processor.
Status of virtual processor 4 as of: 05/08/2009 09:53:17
  on-line since 05/03/2009 00:05:18.
  The i386 processor operates at 2612 MHz,
        and has an i387 compatible floating point processor.
Status of virtual processor 5 as of: 05/08/2009 09:53:17
  on-line since 05/03/2009 00:05:20.
  The i386 processor operates at 2612 MHz,
        and has an i387 compatible floating point processor.
Status of virtual processor 6 as of: 05/08/2009 09:53:17
  on-line since 05/03/2009 00:05:22.
  The i386 processor operates at 2612 MHz,
        and has an i387 compatible floating point processor.
Status of virtual processor 7 as of: 05/08/2009 09:53:17
  on-line since 05/03/2009 00:05:24.
  The i386 processor operates at 2612 MHz,
        and has an i387 compatible floating point processor.
&lt;/font&gt;&lt;/pre&gt;

&lt;b&gt;&lt;font color="#000099"&gt;Memory Info:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
In order to find out how much physical memory is installed, use &lt;code&gt;prtconf&lt;/code&gt;:
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;b&gt;sharfah@starship:~&amp;gt;&lt;/b&gt; prtconf | grep Memory
&lt;font color="green"&gt;Memory size: 65536 Megabytes
&lt;/font&gt;&lt;/pre&gt;

&lt;b&gt;&lt;font color="#000099"&gt;Version Info:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
To show machine, software revision and patch revision information use the &lt;code&gt;showrev&lt;/code&gt; command:
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;b&gt;sharfah@starship:~&amp;gt;&lt;/b&gt; showrev
&lt;font color="green"&gt;Hostname: starship
Hostid: 80f32709
Release: 5.10
Kernel architecture: i86pc
Application architecture: i386
Hardware provider:
Kernel version: SunOS 5.10 Generic_137112-06&lt;/font&gt;&lt;/pre&gt;
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;b&gt;sharfah@starship:~&amp;gt;&lt;/b&gt; uname -a
&lt;font color="green"&gt;SunOS starship 5.10 Generic_137112-06 i86pc i386 i86pc&lt;/font&gt;&lt;/pre&gt;

&lt;b&gt;&lt;font color="#000099"&gt;Processes:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
In order to list the processes running, use &lt;code&gt;prstat&lt;/code&gt; (equivalent to &lt;code&gt;top&lt;/code&gt;).
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;b&gt;sharfah@starship:~&amp;gt;&lt;/b&gt; prstat
&lt;font color="green"&gt;  PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU PROCESS/NLWP
 4049 sharfah   1008K  840K sleep    0    0   0:03.17 0.3% find/1
14632 sharfah      114M   68M sleep   29   10   1:19.18 0.1% java/30
&lt;/font&gt;&lt;/pre&gt;

&lt;b&gt;&lt;font color="#000099"&gt;Related posts:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
&lt;a href="http://fahdshariff.blogspot.com/2006/12/linux-cpu-memory-and-version.html"&gt;Linux - CPU, Memory and Version&lt;/a&gt;&lt;br/&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-923749305507621976?l=fahdshariff.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/923749305507621976/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2009/05/solaris-cpu-memory-and-version.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/923749305507621976?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/923749305507621976?v=2" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/2009/05/solaris-cpu-memory-and-version.html" title="Solaris - CPU, Memory and Version" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11444574926882287120" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></entry><entry gd:etag="W/&quot;CEcAQ3Y-fyp7ImA9WxJSF0w.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-7539682929817724934</id><published>2009-05-07T17:00:00.000+01:00</published><updated>2009-05-07T17:00:42.857+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-07T17:00:42.857+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sqlplus" /><category scheme="http://www.blogger.com/atom/ns#" term="Oracle" /><category scheme="http://www.blogger.com/atom/ns#" term="shell" /><category scheme="http://www.blogger.com/atom/ns#" term="scripting" /><title>Creating a Report with SQLPlus</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
For those of you who have used SQL*Plus, you will know that it is a nightmare to get the output looking just the way you want it to. You have to battle with page sizes and column widths. (Why isn't there an option to set the column size automatically, I wonder?)
&lt;p/&gt;
Here are a few things that I have learnt:
&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Silent Mode&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
Use the &lt;code&gt;-s&lt;/code&gt; flag on your sqlplus command in order to inhibit output such as the SQL*Plus banner and prompt.

&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Spooling to a file&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
You need to spool in order to write the output of your sql commands to a file. Turn it off when you are done.
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
SQL&gt; spool results.out
SQL&gt; select 1 from dual;
SQL&gt; spool off
&lt;/pre&gt;

&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Page Size&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
This refers to the number of rows on a single page. The default is 14 which means that after 14 lines, your table header will be repeated, which is ugly! In order to get around this, set your page size to the maximum of 50000. It would be nice if you could set it to &lt;i&gt;unlimited&lt;/i&gt;.
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
SQL&gt; show pagesize;
pagesize 24
SQL&gt; set pagesize 50000&lt;/pre&gt;

&lt;b&gt;&lt;font color="#000099"&gt;Line Size&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
This refers to how long your line can get before it wraps to the next line. If you are not sure how long your line can be, set the size to the maximum of 32767 and turn on trimspool in order to remove trailing blanks from your spooled file.
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
SQL&gt; show linesize;
pagesize 80
SQL&gt; set linesize 32767
SQL&gt; set trimspool on&lt;/pre&gt;

&lt;b&gt;&lt;font color="#000099"&gt;Column Size&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
You can specify the size of individual columns like this:
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
SQL&gt; col employee_name format a40
&lt;/pre&gt;

&lt;b&gt;&lt;font color="#000099"&gt;Titles&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
Use TTITLE to display a heading before you run a query.
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
SQL&gt; TTITLE LEFT 'My table heading'
SQL&gt; select 1 from dual;

My table heading
         1
----------
         1
&lt;/pre&gt;
Use SKIP to skip lines e.g. SKIP 2 would be equivalent to pressing &lt;code&gt;Return&lt;/code&gt; twice.
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
SQL&gt; ttitle left 'My table heading' -
&gt; SKIP 2 'Another heading' SKIP 2
SQL&gt; select 1 from dual;

My table heading

Another heading

         1
----------
         1
&lt;/pre&gt;

&lt;b&gt;&lt;font color="#000099"&gt;Example script&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
The shell script below uses SQL*Plus to create a report.
&lt;pre name="code" class="sql:nogutter:nocontrols"&gt;
#! /usr/bin/sh

#the file where sql output will go
OUT=/report/path/report.txt

#email this report?
EMAIL=Y

#oracle variables
ORACLE_HOME=/path/oracle/client
export ORACLE_HOME
SQLPLUS=$ORACLE_HOME/bin/sqlplus
export SQLPLUS
LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH
TNS_ADMIN=/path/tnsnames
export TNS_ADMIN

#######################
#sqlplus - silent mode
#redirect /dev/null so that output is not shown on terminal
$SQLPLUS -s "user/pass@database" &amp;lt;&amp;lt; END_SQL &amp;gt; /dev/null

SET ECHO OFF
SET TERMOUT OFF

SET PAGESIZE 50000

SET LINESIZE 32767
SET TRIMSPOOL ON

COL EMPLOYEE_NAME FORMAT A40

SPOOL $OUT

TTITLE LEFT 'EMPLOYEE REPORT' -
SKIP 2 LEFT 'Number of Employees:' SKIP 2

SELECT COUNT(*) AS total FROM employee
/

TTITLE LEFT 'Employee Names' SKIP 2

SELECT employee_name FROM employee
ORDER BY employee_name DESC
/

SPOOL OFF

END_SQL
#######################

#change tabs to spaces
expand $OUT &amp;gt; $OUT.new
mv $OUT.new $OUT

echo Finished writing report $OUT

if [ "$EMAIL" = "Y" ]
then
 to=someone@abc.com
 subject="Employee Report"
 mailx -s "$subject" $to &amp;lt; $OUT
 echo "Emailed report"
fi
&lt;/pre&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-7539682929817724934?l=fahdshariff.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/7539682929817724934/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2009/05/creating-report-with-sqlplus.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/7539682929817724934?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/7539682929817724934?v=2" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/2009/05/creating-report-with-sqlplus.html" title="Creating a Report with SQLPlus" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11444574926882287120" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CU4BSHY7eCp7ImA9WxJSFk8.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-974176877084469954</id><published>2009-05-06T16:32:00.000+01:00</published><updated>2009-05-06T16:32:39.800+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-06T16:32:39.800+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="release" /><category scheme="http://www.blogger.com/atom/ns#" term="maven" /><title>Maven Release</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Prepare the release&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
Run the following command:
&lt;pre name="code" class="xml:nogutter:nocontrols"&gt;
mvn release:prepare
&lt;/pre&gt;
This command will prompt you for a release version name, the next version name and will tag the code in CVS.&lt;p/&gt;

For example, if the current version in your pom is 1_10-SNAPSHOT, after running &lt;code&gt;release:prepare&lt;/code&gt;, the version will be changed to 1_10, maven will commit (with a comment of &lt;i&gt;[maven-release-plugin] prepare release myapp-1_10&lt;/i&gt;), tag as myapp-1_10, bump the pom version to 1_11-SNAPSHOT and commit it (with a comment of &lt;i&gt;[maven-release-plugin] prepare for next development iteration&lt;/i&gt;).
&lt;p/&gt;
&lt;code&gt;release:prepare&lt;/code&gt; will also create a file called &lt;i&gt;release.properties&lt;/i&gt;, shown below:
&lt;pre name="code" class="xml:nogutter:nocontrols"&gt;
maven.username=sharfah
checkpoint.transformed-pom-for-release=OK
scm.tag=myapp-1_10
scm.url=scm:cvs:pserver::@sourceforge.uk.db.com:/data/cvsroot/apps:MyApp
checkpoint.transform-pom-for-development=OK
checkpoint.local-modifications-checked=OK
checkpoint.initialized=OK
checkpoint.checked-in-release-version=OK
checkpoint.tagged-release=OK
checkpoint.prepared-release=OK
checkpoint.check-in-development-version=OK
&lt;/pre&gt;

&lt;b&gt;&lt;font color="#000099"&gt;Perform the release&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
Run the following command:
&lt;pre name="code" class="xml:nogutter:nocontrols"&gt;
mvn release:perform
&lt;/pre&gt;
This will use the &lt;i&gt;release.properties&lt;/i&gt; file in order to check-out the tagged version from source control, compile, test and deploy it to the maven repository. If you have deleted your &lt;i&gt;release.properties&lt;/i&gt; file, don't worry, you can just create a dummy one yourself, using the sample above.
&lt;p/&gt;
If you want to skip site-deploy run the following command instead:
&lt;pre name="code" class="xml:nogutter:nocontrols"&gt;
mvn release:perform -Dgoals=deploy
&lt;/pre&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Related posts:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
&lt;a href="http://fahdshariff.blogspot.com/2009/02/quick-maven-commands.html"&gt;Quick Maven Commands&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://fahdshariff.blogspot.com/2008/06/skip-tests-in-maven-tip.html"&gt;Skip Tests in Maven&lt;/a&gt;&lt;br/&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-974176877084469954?l=fahdshariff.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/974176877084469954/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2009/05/maven-release.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/974176877084469954?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/974176877084469954?v=2" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/2009/05/maven-release.html" title="Maven Release" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11444574926882287120" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;D0QNRHwyeip7ImA9WxJTGU4.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-7678417719769304339</id><published>2009-04-28T17:16:00.000+01:00</published><updated>2009-04-28T17:16:35.292+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-28T17:16:35.292+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="UNIX" /><category scheme="http://www.blogger.com/atom/ns#" term="Linux" /><category scheme="http://www.blogger.com/atom/ns#" term="Windows" /><category scheme="http://www.blogger.com/atom/ns#" term="samba" /><category scheme="http://www.blogger.com/atom/ns#" term="Ubuntu" /><title>Setup Samba on Ubuntu</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
Here is a quick guide to setting up a Samba share on Ubuntu Linux.
&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Install the package&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;b&gt;&lt;font color="green"&gt;sudo apt-get install samba smbfs&lt;/font&gt;&lt;/b&gt;
&lt;/pre&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Edit smb.conf&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
Open the samba configuration file in your favourite editor, change security to user and add a username map.
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;b&gt;&lt;font color="green"&gt;sudo vi /etc/samba/smb.conf&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
# "security = user" is always a good idea. This will require a Unix account
# in this server for every user accessing the server. See
# /usr/share/doc/samba-doc/htmldocs/Samba3-HOWTO/ServerType.html
# in the samba-doc package for details.
&lt;b&gt;security = user&lt;/b&gt;
&lt;b&gt;username map = /etc/samba/smbusers&lt;/b&gt;
&lt;/pre&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Create a samba user&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;b&gt;&lt;font color="green"&gt;sudo smbpasswd -a fahd&lt;/font&gt;&lt;/b&gt;
&lt;/pre&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Add the new user to the smbusers file&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
The format is "unix username" = "samba username".
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;b&gt;&lt;font color="green"&gt;sudo vi /etc/samba/smbusers&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
fahd = fahd
&lt;/pre&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Share home directory&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
Make the following changes to smb.conf in order to share your home directory over samba and make it writable.
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;b&gt;&lt;font color="green"&gt;sudo vi /etc/samba/smb.conf&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
#======================= Share Definitions =======================

# Un-comment the following (and tweak the other settings below to suit)
# to enable the default home directory shares.  This will share each
# user's home directory as \\server\username
&lt;b&gt;[homes]&lt;/b&gt;
&lt;b&gt;   comment = Home Directories&lt;/b&gt;
&lt;b&gt;   browseable = no&lt;/b&gt;

# By default, the home directories are exported read-only. Change the
# next parameter to 'no' if you want to be able to write to them.
&lt;b&gt;   read only = no&lt;/b&gt;

# By default, \\server\username shares can be connected to by anyone
# with access to the samba server.  Un-comment the following parameter
# to make sure that only "username" can connect to \\server\username
# This might need tweaking when using external authentication schemes
&lt;b&gt;   valid users = %S&lt;/b&gt;
&lt;/pre&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Connecting to the samba&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
Now you should be able to map a drive on windows using the following share format: &lt;b&gt;\\ubuntumachine\username&lt;/b&gt;. The first time you will be prompted for a username and password.&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Restarting samba&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;b&gt;&lt;font color="green"&gt;sudo /etc/init.d/samba restart&lt;/font&gt;&lt;/b&gt;
&lt;/pre&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-7678417719769304339?l=fahdshariff.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/7678417719769304339/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2009/04/setup-samba-on-ubuntu.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/7678417719769304339?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/7678417719769304339?v=2" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/2009/04/setup-samba-on-ubuntu.html" title="Setup Samba on Ubuntu" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11444574926882287120" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></entry><entry gd:etag="W/&quot;C04BRX05fip7ImA9WxVbFU8.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-3776463278085472251</id><published>2009-03-31T18:52:00.000+01:00</published><updated>2009-03-31T18:52:34.326+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-31T18:52:34.326+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="graphs" /><category scheme="http://www.blogger.com/atom/ns#" term="charts" /><category scheme="http://www.blogger.com/atom/ns#" term="&quot;google chart api&quot;" /><category scheme="http://www.blogger.com/atom/ns#" term="google" /><category scheme="http://www.blogger.com/atom/ns#" term="webdesign" /><title>100th post: Using Google Charts</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
This is my 100th blog entry! I would like to take this opportunity to thank everyone who has stopped by to read, comment or share something on this blog and make it a success. I started &lt;a href="http://fahdshariff.blogspot.com"&gt;fahd.blog&lt;/a&gt; in August 2006 mainly to document my experiences with new technologies and also to share tips and tricks that I have learnt with the rest of the world. I don't plan to stop here, so stay tuned for more interesting posts!
&lt;p/&gt;
In this post, I'm going to be using the &lt;a href="http://code.google.com/apis/chart/"&gt;Google Chart API&lt;/a&gt; to dynamically create charts illustrating the frequency of my blog posts over the last few years. This API allows you to specify all your data within a URL and have Google create the chart image for you.
&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Bar Chart&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
I'm going to draw a bar chart to show the number of posts per month, since 2006. &lt;br/&gt;The chart parameters I will use are:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cht=bhs&lt;/code&gt; (horizontal bar chart)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chs=400x600&lt;/code&gt; (size)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chd=t:5,6,2,2,2,2,3,7,...&lt;/code&gt; (data)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chds=0,10&lt;/code&gt; (data scale - min/max)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chxt=x,y,x&lt;/code&gt; (axes)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chxl=0:|0|1|...|1:|Aug-06|Sep-06|...|2:||Number|&lt;/code&gt; (axis labels)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chco=76A4FB&lt;/code&gt; (colour)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chtt=Blog Posts by Month&lt;/code&gt; (title)&lt;/li&gt;
&lt;/ul&gt;
This generates the following image:&lt;p/&gt;
&lt;code&gt;
&amp;lt;img src="http://chart.apis.google.com/chart?cht=bhs&amp;chbh=a&amp;chs=400x600&amp;chd=t:5,6,2,2,2,2,3,7,10,9,3,5,0,1,0,1,0,2,2,1,0,1,0,0,4,5,5,4,7,2,2,7&amp;chds=0,10&amp;chxt=x,y&amp;chxl=0:|0|1|2|3|4|5|6|7|8|9|10|1:|Aug-06|Sep-06|Oct-06|Nov-06|Dec-06|Jan-07|Feb-07|Mar-07|Apr-07|May-07|Jun-07|Jul-07|Aug-07|Sep-07|Oct-07|Nov-07|Dec-07|Jan-08|Feb-08|Mar-08|Apr-08|May-08|Jun-08|Jul-08|Aug-08|Sep-08|Oct-08|Nov-08|Dec-08|Jan-09|Feb-09|Mar-09&amp;chtt=Blog Posts by Month&amp;chco=76A4FB"/&amp;gt;&lt;/code&gt;
&lt;p/&gt;
&lt;img src="http://chart.apis.google.com/chart?cht=bhs&amp;chbh=a&amp;chs=400x600&amp;chd=t:5,6,2,2,2,2,3,7,10,9,3,5,0,1,0,1,0,2,2,1,0,1,0,0,4,5,5,4,7,2,2,7&amp;chds=0,10&amp;chxt=x,y,x&amp;chxl=0:|0|1|2|3|4|5|6|7|8|9|10|1:|Aug-06|Sep-06|Oct-06|Nov-06|Dec-06|Jan-07|Feb-07|Mar-07|Apr-07|May-07|Jun-07|Jul-07|Aug-07|Sep-07|Oct-07|Nov-07|Dec-07|Jan-08|Feb-08|Mar-08|Apr-08|May-08|Jun-08|Jul-08|Aug-08|Sep-08|Oct-08|Nov-08|Dec-08|Jan-09|Feb-09|Mar-09|2:||Number of posts|&amp;chtt=Blog Posts by Month&amp;chco=76A4FB" /&gt;
&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Line Chart&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
Here's the same data put into a line chart. &lt;br/&gt;The chart parameters I will use are:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cht=lc&lt;/code&gt; (line chart)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chs=400x300&lt;/code&gt; (size)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chd=t:7,2,2,7,4,5,...&lt;/code&gt; (data)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chds=0,10&lt;/code&gt; (data scale - min/max)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chxt=y,x&lt;/code&gt; (axes)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chxl=0:|0|1|...|1:|Aug-06|...&lt;/code&gt; (axis labels)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chco=80C65A&lt;/code&gt; (colour)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chm=o,FF0000,0,-1,5.0|V,3399CC,0,23,0.5&lt;/code&gt; (circle each point; vertical line at peak)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chtt=Blog Posts by Month&lt;/code&gt; (title)&lt;/li&gt;
&lt;/ul&gt;
This generates the following image:&lt;p/&gt;
&lt;code&gt;
&amp;lt;img src="http://chart.apis.google.com/chart?cht=lc&amp;chbh=a&amp;chs=400x300&amp;chco=80C65A&amp;chds=0,10&amp;chd=t:7,2,2,7,4,5,5,4,0,0,1,0,1,2,2,0,1,0,1,0,5,3,9,10,7,3,2,2,2,2,6,5&amp;chxt=y,x&amp;chxl=0:|0|1|2|3|4|5|6|7|8|9|10|1:|Aug-06|Apr-07|Nov-07|Jul-08|Mar-09&amp;chm=o,FF0000,0,-1,5.0|V,3399CC,0,23,0.5&amp;chtt=Blog Posts by Month"/&amp;gt;&lt;/code&gt;
&lt;p/&gt;
&lt;img src="http://chart.apis.google.com/chart?cht=lc&amp;chbh=a&amp;chs=400x300&amp;chco=80C65A&amp;chds=0,10&amp;chd=t:7,2,2,7,4,5,5,4,0,0,1,0,1,2,2,0,1,0,1,0,5,3,9,10,7,3,2,2,2,2,6,5&amp;chxt=y,x&amp;chxl=0:|0|1|2|3|4|5|6|7|8|9|10|1:|Aug-06|Apr-07|Nov-07|Jul-08|Mar-09&amp;chm=o,FF0000,0,-1,5.0|V,3399CC,0,23,0.5&amp;chtt=Blog Posts by Month" /&gt;
&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Pie Chart&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
I'm going to use a Pie Chart to show the number of posts per year. &lt;br/&gt;The chart parameters I will use are:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cht=p3&lt;/code&gt; (3D pie chart)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chs=270x120&lt;/code&gt; (size)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chd=t:22,21,44,13&lt;/code&gt; (data)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chl=2006|2007|2008|2009&lt;/code&gt; (label)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chtt=Blog Posts by Year&lt;/code&gt; (title)&lt;/li&gt;
&lt;/ul&gt;
This generates the following image:&lt;p/&gt;
&lt;code&gt;&amp;lt;img src="http://chart.apis.google.com/chart?cht=p3&amp;chs=270x120&amp;chd=t:22,21,44,13&amp;chl=2006|2007|2008|2009&amp;chtt=Blog Posts by Year"/&amp;gt;&lt;/code&gt;
&lt;p/&gt;
&lt;img src="http://chart.apis.google.com/chart?cht=p3&amp;chs=270x120&amp;chd=t:22,21,44,13&amp;chl=2006|2007|2008|2009&amp;chtt=Blog Posts by Year"/&gt;
&lt;p/&gt;
As can be seen above, the Chart API is very powerful and allows you to produce different types of charts and customise them with different styles. However, in my opinion, the API is not intuitive and the URLs are quite cryptic. I doubt I will remember how to use the API without having it open in front of me!
&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;References:&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
&lt;a href="http://code.google.com/apis/chart/"&gt;Google Chart API&lt;/a&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-3776463278085472251?l=fahdshariff.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/3776463278085472251/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2009/03/100th-post-using-google-charts.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/3776463278085472251?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/3776463278085472251?v=2" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/2009/03/100th-post-using-google-charts.html" title="100th post: Using Google Charts" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11444574926882287120" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total></entry><entry gd:etag="W/&quot;Ck8DRXs4cCp7ImA9WxVbFE4.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-294076645342212751</id><published>2009-03-30T17:34:00.002+01:00</published><updated>2009-03-30T17:34:34.538+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-30T17:34:34.538+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="UNIX" /><category scheme="http://www.blogger.com/atom/ns#" term="shell" /><category scheme="http://www.blogger.com/atom/ns#" term="scripting" /><title>Named Pipes with mkfifo [Unix]</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
Named pipes are useful for inter-process communication. Unlike anonymous pipes, any number of readers and writers can use a named pipe. They are very useful for letting other processes know that something has happened e.g. a file has been created etc.
&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;Creating a named pipe&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
You can create a named pipe using the &lt;code&gt;mkfifo&lt;/code&gt; command, which creates a special pipe file that remains in place until it is removed. Since it is a type of file, you can use the &lt;code&gt;rm&lt;/code&gt; command to remove it when you are done.
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;b&gt;sharfah@firefly:~&amp;gt;&lt;/b&gt; mkfifo mypipe
&lt;b&gt;sharfah@firefly:~&amp;gt;&lt;/b&gt; ls
&lt;font color="green"&gt;mypipe|&lt;/font&gt;&lt;/pre&gt;

&lt;b&gt;&lt;font color="#000099"&gt;Writing to a named pipe&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
Since a named pipe is just a special type of file, you can write to it just as you would normally write to a file. However, if there are no processes reading from the pipe, the write call will block.
&lt;p/&gt;
The following example script writes numbers into the pipe. If there are no readers, it will block on line 5.
&lt;pre name="code" class="java:nogutter:nocontrols"&gt;
COUNT=1
while (true)
do
 echo Writer$$: $COUNT
 echo $COUNT &amp;gt; mypipe
 COUNT=`expr $COUNT + 1`
 sleep 1
done
&lt;/pre&gt;

&lt;b&gt;&lt;font color="#000099"&gt;Reading from a named pipe&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
Reading from a named pipe is the same as reading from a normal file. You can &lt;code&gt;cat&lt;/code&gt; a named pipe, &lt;code&gt;tail&lt;/code&gt; it or &lt;code&gt;read&lt;/code&gt; it as follows:
&lt;pre name="code" class="java:nogutter:nocontrols"&gt;
while (true)
do
   read line &amp;lt; mypipe
   echo Reader$$: $line
done
&lt;/pre&gt;

&lt;b&gt;&lt;font color="#000099"&gt;Multiple readers&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
If you have multiple readers reading from the same pipe, only one of the readers will receive the output. This is illustrated with the following example, in which I have launched one writer and two readers:
&lt;pre style="font-family: Consolas,Courier New,Courier,mono,serif; font-size:12px;"&gt;
&lt;b&gt;sharfah@firefly:~&amp;gt;&lt;/b&gt; writer.sh&amp; reader.sh&amp; reader.sh&amp;
&lt;font color="silver"&gt;Writer10500: 1 &lt;/font&gt;
&lt;font color="green"&gt;Reader10501: 1 &lt;/font&gt;
&lt;font color="silver"&gt;Writer10500: 2 &lt;/font&gt;
&lt;font color="maroon"&gt;Reader10502: &lt;/font&gt;
&lt;font color="green"&gt;Reader10501: 2 &lt;/font&gt;
&lt;font color="silver"&gt;Writer10500: 3 &lt;/font&gt;
&lt;font color="green"&gt;Reader10501: 3 &lt;/font&gt;
&lt;font color="maroon"&gt;Reader10502: &lt;/font&gt;
&lt;font color="silver"&gt;Writer10500: 4 &lt;/font&gt;
&lt;font color="green"&gt;Reader10501: &lt;/font&gt;
&lt;font color="maroon"&gt;Reader10502: 4 &lt;/font&gt;
&lt;font color="silver"&gt;Writer10500: 5 &lt;/font&gt;
&lt;font color="maroon"&gt;Reader10502: 5 &lt;/font&gt;
&lt;font color="green"&gt;Reader10501: &lt;/font&gt;
&lt;font color="silver"&gt;Writer10500: 6 &lt;/font&gt;
&lt;font color="green"&gt;Reader10501: 6 &lt;/font&gt;
&lt;font color="maroon"&gt;Reader10502: &lt;/font&gt;
&lt;font color="silver"&gt;Writer10500: 7 &lt;/font&gt;
&lt;font color="maroon"&gt;Reader10502: 7 &lt;/font&gt;
&lt;font color="green"&gt;Reader10501: &lt;/font&gt;
&lt;font color="silver"&gt;Writer10500: 8 &lt;/font&gt;
&lt;font color="maroon"&gt;Reader10502: 8 &lt;/font&gt;
&lt;font color="green"&gt;Reader10501: &lt;/font&gt;
&lt;font color="silver"&gt;Writer10500: 9 &lt;/font&gt;
&lt;font color="green"&gt;Reader10501: 9 &lt;/font&gt;
&lt;font color="maroon"&gt;Reader10502: &lt;/font&gt;
&lt;font color="silver"&gt;Writer10500: 10 &lt;/font&gt;
&lt;font color="maroon"&gt;Reader10502: 10 &lt;/font&gt;&lt;/pre&gt;

&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-294076645342212751?l=fahdshariff.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/294076645342212751/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2009/03/named-pipes-with-mkfifo-unix.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/294076645342212751?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/294076645342212751?v=2" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/2009/03/named-pipes-with-mkfifo-unix.html" title="Named Pipes with mkfifo [Unix]" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11444574926882287120" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></entry><entry gd:etag="W/&quot;DkINQng_fyp7ImA9WxVUFUU.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-1166192582704231675</id><published>2009-03-20T21:29:00.000Z</published><updated>2009-03-20T21:29:53.647Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-20T21:29:53.647Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="&quot;vertical rush&quot;" /><category scheme="http://www.blogger.com/atom/ns#" term="stairs" /><category scheme="http://www.blogger.com/atom/ns#" term="climb" /><title>Vertical Rush Results</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
Yesterday, I climbed Tower 42 with my team, "Are we there yet?". We got there at 11.30am, wearing our black, Vertical Rush t-shirts and our race numbers pinned on. Our chip timers were tied to our shoes. Then the race started. They let us off in small batches so that we wouldn't clog the stairwell. I started off quick, taking two stairs at a time, but by the time I got halfway, I felt my energy running out. I could hear my heart pounding in my chest and I changed to taking single stairs and dragging myself up using the banisters. 
&lt;p/&gt;
I finally made it to the top and staggered into the lounge where I was given a "goodie" bag containing a bottle of water, a disgusting banana energy gel and a Tower 42 mouse mat! There were no chairs, so I slumped onto the floor and enjoyed my water. It has never tasted so good!
&lt;p/&gt;
We then had some team photos taken at the top, which I now have to buy! Sadly, they didn't allow any cameras or mobile phones into the race, so I wasn't able to take any pictures myself.
&lt;p/&gt;
In the evening, there was a prize-giving ceremony at Gibson Hall where we found out our times and got a certificate for taking part. Nearly 600 people took part in the race and the fastest time was 00:04:22!
&lt;p/&gt;
&lt;b&gt;&lt;font color="#000099"&gt;My Stats&lt;/font&gt;&lt;/b&gt;&lt;br/&gt;
&lt;b&gt;Race Number:&lt;/b&gt; 5034  &lt;br/&gt;
&lt;b&gt;Gender Position:&lt;/b&gt; 341  &lt;br/&gt;
&lt;b&gt;Category:&lt;/b&gt; Financial  &lt;br/&gt;
&lt;b&gt;Category Position:&lt;/b&gt; 100  &lt;br/&gt;
&lt;b&gt;Club:&lt;/b&gt; Deutsche Bank  &lt;br/&gt;
&lt;b&gt;Chip Time:&lt;/b&gt; 00:09:10   &lt;br/&gt;
&lt;b&gt;Chip Position:&lt;/b&gt; 382&lt;br/&gt;
&lt;p/&gt;
I'm also really proud about how much we raised for Shelter! Here is our Just Giving page: &lt;a href="http://www.justgiving.com/reteamstairclimb"&gt;http://www.justgiving.com/reteamstairclimb&lt;/a&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-1166192582704231675?l=fahdshariff.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/1166192582704231675/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2009/03/vertical-rush-results.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/1166192582704231675?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/1166192582704231675?v=2" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/2009/03/vertical-rush-results.html" title="Vertical Rush Results" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11444574926882287120" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><georss:point>51.5152901 -0.0840905</georss:point></entry><entry gd:etag="W/&quot;CkcDSXs5fCp7ImA9WxVVFk0.&quot;"><id>tag:blogger.com,1999:blog-32637828.post-4402222312659699941</id><published>2009-03-09T12:01:00.000Z</published><updated>2009-03-09T12:01:18.524Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-09T12:01:18.524Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="&quot;vertical rush&quot; stairs climb" /><title>Vertical Rush</title><content type="html">&lt;span style="font-family: arial,sans-serif;"&gt;
I've been crazy enough to sign up for &lt;a href="http://england.shelter.org.uk/what_you_can_do/events_and_challenges/vertical_rush"&gt;Vertical Rush&lt;/a&gt;, a race to the top of &lt;a href="http://en.wikipedia.org/wiki/Tower_42"&gt;Tower 42&lt;/a&gt;, the tallest building in the City of London. The event, which is going to take place on the 19th of March, involves running or walking 183m (600ft) up 920 stairs and 42 floors to the top of the tower. All of this is in aid of the vulnerably housed and homeless charity &lt;a href="http://england.shelter.org.uk"&gt;Shelter&lt;/a&gt;.
&lt;p/&gt;
&lt;center&gt;&lt;img alt="Tower 42 is the tallest building in the City of London" src="http://upload.wikimedia.org/wikipedia/commons/thumb/5/55/Tower42.jpg/180px-Tower42.jpg" width="180" height="301" border="0" /&gt;&lt;/center&gt;
&lt;p/&gt;
I'm not doing this alone. I have a team of four others from work and we're calling ourselves, "Are we there yet?". We've been climbing 400 stairs (24 floors) in our office every day for the last couple of months, but this is going to be a lot more painful!
&lt;p/&gt;
Please help to motivate us to the top by sponsoring us through our Just Giving page: &lt;a href="http://www.justgiving.com/reteamstairclimb"&gt;http://www.justgiving.com/reteamstairclimb&lt;/a&gt;
&lt;p/&gt;
Stay tuned to find out how long it takes me to climb the tower!
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/32637828-4402222312659699941?l=fahdshariff.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://fahdshariff.blogspot.com/feeds/4402222312659699941/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://fahdshariff.blogspot.com/2009/03/vertical-rush.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/4402222312659699941?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/32637828/posts/default/4402222312659699941?v=2" /><link rel="alternate" type="text/html" href="http://fahdshariff.blogspot.com/2009/03/vertical-rush.html" title="Vertical Rush" /><author><name>Fahd Shariff</name><uri>http://www.blogger.com/profile/00919911016127601294</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="11444574926882287120" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry></feed>
