<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Digitally Enlightened</title>
    <description>Stateless observations of transient digital world</description>
    <link>https://vayudoot.org/</link>
    <atom:link href="https://vayudoot.org/sitemap.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Fri, 20 Feb 2026 00:55:02 +0000</pubDate>
    <lastBuildDate>Fri, 20 Feb 2026 00:55:02 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>Shell scripting best practices</title>
        <description>&lt;p&gt;Majority of time shell script is used for doing some “hack” job of sewing together various utilities and their output. While shell scripting is easy and straight-forward most of the time, it does pop surprises time to time. End result is not just bugs but silent bugs. It would save lot of headache and debugging hours to treat shell scripting as proper programming language and use coding discipline as demanded by other high level languages. For very complex jobs, it might be worth considering python, as after all shell scripting comes with very limited vernacular. Following are some pointers for robust shell programming. Note that there are variations between various shells and POSIX standard. You might want to try out and change usage accordingly.&lt;/p&gt;

&lt;h1 id=&quot;environment&quot;&gt;Environment&lt;/h1&gt;
&lt;p&gt;Using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;env&lt;/code&gt; ensures portability vs using direct path to shell.&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;declare-variables&quot;&gt;Declare variables&lt;/h1&gt;
&lt;p&gt;It is a good practice to declare variables upfront in shell script. Global variables should be upper case and local should be declared early in function.&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;GLOBAL_VAR&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
foo&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;var1 &lt;span class=&quot;nv&quot;&gt;var2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0
  &lt;span class=&quot;nv&quot;&gt;var1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;GLOBAL_VAR&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:-&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# if GLOBAL_VAR is empty use 100 as default&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Notice, no use of keyword ‘function’.
Also, surround variables in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{}&lt;/code&gt; to avoid shell incorrectly interpreting variable name.
For special built-in variables like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$@&lt;/code&gt;, always use quotes.&lt;/p&gt;

&lt;h1 id=&quot;prefer--over-&quot;&gt;Prefer &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[[&lt;/code&gt; over &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[&lt;/code&gt;&lt;/h1&gt;
&lt;p&gt;While &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[&lt;/code&gt; makes your script portable (as this is POSIX compliant condition test), all shell support &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[[&lt;/code&gt; now which is more robust and extends functionality. With &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[[&lt;/code&gt; conditional construct, quotes are not needed for variables, supports extended pattern matching, multiple conditions can be naturally combined (instead using -o or -a etc), and various other things.&lt;/p&gt;

&lt;h1 id=&quot;exit-if-externally-sourced-file-doesnt-exist&quot;&gt;Exit if externally sourced file doesn’t exist&lt;/h1&gt;
&lt;p&gt;Instead of sourcing an external file and moving on, use circuit breaker to exit immediately. Otherwise, your script might continue and either print lot of error messages or even silently corrupt data, depending on what was used from external file.&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt; common_file &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;check-return-code-of-all-external-commands-or-utils&quot;&gt;Check return code of all external commands or utils&lt;/h1&gt;
&lt;p&gt;If an external command can fail, then check it’s return code. Such commands can also be wrapped in a general function.&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt; cmd &lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$?&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-ne&lt;/span&gt; 0 &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;use-whitespace-with--&quot;&gt;Use whitespace with $( )&lt;/h1&gt;
&lt;p&gt;Makes it easier to read.&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;PROGNAME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;basename&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$0&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;use--instead-of-&quot;&gt;Use $() instead of ``&lt;/h1&gt;
&lt;p&gt;For command substitution, use $(). The commands can be further nested with it.&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;last_line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt; dmesg | &lt;span class=&quot;nb&quot;&gt;tail&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-n1&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;all_lines&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;cat &lt;/span&gt;file &lt;span class=&quot;si&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;when-changing-directories-use-directory-stack&quot;&gt;When changing directories, use directory stack&lt;/h1&gt;
&lt;p&gt;If supported by your shell, it’s better to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pushd&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;popd&lt;/code&gt; for saving and returning current working directory instead explicitly using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;pushd&lt;/span&gt; /tmp&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;use-var&quot;&gt;Use ((var++))&lt;/h1&gt;
&lt;p&gt;Instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;let var=var+1&lt;/code&gt;. Same for substraction and other arithmatics.&lt;/p&gt;

&lt;h1 id=&quot;use-regex-expression&quot;&gt;Use regex expression&lt;/h1&gt;
&lt;p&gt;For complex regular expressions, use a separate variable for regex pattern.&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;re&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;^[0-9]{2}-[0-9]{4}-[0-9]{2} *$&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$serial_num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;~ &lt;span class=&quot;nv&quot;&gt;$re&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;use-signal-traps-for-cleanup&quot;&gt;Use signal traps for cleanup&lt;/h1&gt;
&lt;p&gt;Traps can be used to clean temporary resources (lockfiles, temp files), or even rollback to previous state (say if setup of files were being modified and one failed).&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;trap &lt;/span&gt;cleanup EXIT INT TERM
cleanup&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Cleaning up resources ...&quot;&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$lockfile&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;e[2J&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;e[H&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;e[m    &lt;span class=&quot;c&quot;&gt;# cls&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;trap&lt;/span&gt; - EXIT INT TERM       &lt;span class=&quot;c&quot;&gt;# clear traps and exit&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;0
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;use-set-builtins-for-robust-script&quot;&gt;Use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set&lt;/code&gt; builtins for robust script&lt;/h1&gt;
&lt;p&gt;These options could be either set globally, for a function, or whithin a block, depending context. Some of the most common and useful ones are listed below.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;errexit&lt;/code&gt; (-e) makes your script exit when failure occurs. You can allow script to continue on a failing command by adding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;|| true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nounset&lt;/code&gt; (-u) exit when your script tries to use undeclared variables.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pipefail&lt;/code&gt; will fail your script if any of command in pipe chain fail. Return code is set to one from failing command. Default is return status of last item in pipe chain.&lt;/p&gt;

&lt;p&gt;Set these options explicitly instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#!/usr/bin/env bash -e&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-euo&lt;/span&gt; pipefail
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;reading-a-file&quot;&gt;Reading a file&lt;/h1&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&amp;lt;&lt;span class=&quot;s2&quot;&gt;&quot;file&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;         &lt;span class=&quot;c&quot;&gt;# to read whole file at once. Make sure size is manageable before reading it.&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;IFS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;$&apos;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;read&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-ra&lt;/span&gt; file &amp;lt; &lt;span class=&quot;s2&quot;&gt;&quot;file&quot;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# read line by line&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;mapfile&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; file &amp;lt; &lt;span class=&quot;s2&quot;&gt;&quot;file&quot;&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;# read line by line. mapfile is available in bash 4.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Also, using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;while read&lt;/code&gt; pattern can be useful in specific situations.&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;{print $2}&apos;&lt;/span&gt; file.txt | &lt;span class=&quot;k&quot;&gt;while &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;read &lt;/span&gt;num
&lt;span class=&quot;k&quot;&gt;do
  if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$num&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;0&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;zero it is!&quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;fi
done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;avoid-temporary-files-for-ephemeral-use&quot;&gt;Avoid temporary files for ephemeral use&lt;/h1&gt;
&lt;p&gt;Instead use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;(cmd)&lt;/code&gt; which transforms output into something which can be used a file.&lt;/p&gt;

&lt;h1 id=&quot;using-lockfiles-without-race-conditions&quot;&gt;Using lockfiles without race conditions&lt;/h1&gt;
&lt;p&gt;First checking if lockfile exists and then creating one if not, obviously has race condition. Following can be used instead.&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; noclobber&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$$&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$lockfile&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; 2&amp;gt; /dev/null&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;then
   &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;trap&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;rm -f &quot;$lockfile&quot;; exit $?&apos;&lt;/span&gt; INT TERM EXIT
   do_critical_section
   &lt;span class=&quot;nb&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$lockfile&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
   &lt;span class=&quot;nb&quot;&gt;trap&lt;/span&gt; - INT TERM EXIT
&lt;span class=&quot;k&quot;&gt;else
   &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;failed to acquire lock, held by &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$lockfile&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On Linux, one can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flock&lt;/code&gt; instead.&lt;/p&gt;

&lt;h1 id=&quot;use-colors-but-with-caution&quot;&gt;Use colors but with caution&lt;/h1&gt;
&lt;p&gt;Using colors, particularly when dumping lot of information, is very useful. However, some terminals might not be able to render colors and could screw up the output.&lt;/p&gt;

&lt;h1 id=&quot;debugging-options&quot;&gt;Debugging options&lt;/h1&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set -n&lt;/code&gt; to dry run the script. Useful to do syntax check.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set -v&lt;/code&gt; to print every command run&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set -x&lt;/code&gt; to trace every command and expanded use&lt;/p&gt;

&lt;p&gt;Instead of setting these variables, it might be useful control debugging behavior via global DEBUG variable. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;echo&lt;/code&gt; can be wrapped around with another print function, which changes verbosity based on DEBUG variable.&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;debug&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;DEBUG&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$*&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;debug-with-function-names&quot;&gt;Debug with function names&lt;/h1&gt;
&lt;p&gt;While printing debug info, FUNCNAME[x] can be used to print current or prior functions in call stack. FUNCNAME[@] is array of all functions in call chain.&lt;/p&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;FUNCNAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[0]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;FUNCNAME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[@]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;use-here-docs-instead-of-individual-prints&quot;&gt;Use here-docs instead of individual prints&lt;/h1&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;EOF&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;
usage: &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PROGNAME&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt; &amp;lt;arg&amp;gt; &amp;lt;arg&amp;gt;
version: 0.1
&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;use-brace-expansion&quot;&gt;Use brace expansion&lt;/h1&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;echo &lt;/span&gt;a&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;d,c,b&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;e    &lt;span class=&quot;c&quot;&gt;# will print - ade ace abe&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo &lt;/span&gt;repos/ntrivedi/code/&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;0,1&lt;span class=&quot;o&quot;&gt;}{&lt;/span&gt;1..9&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;.cpp  &lt;span class=&quot;c&quot;&gt;# cartesian product of two braces&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;use-parameter-expansion&quot;&gt;Use parameter expansion&lt;/h1&gt;
&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;parameter&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:-&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;          &lt;span class=&quot;c&quot;&gt;# if `parameter` unset or null, use `word` as substitute&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;parameter&lt;/span&gt;:&lt;span class=&quot;p&quot;&gt;=word&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;          &lt;span class=&quot;c&quot;&gt;# if `parameter` unset or null, `word` is assigned to parameter&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;parameter&lt;/span&gt;:?word&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;parameter&lt;/span&gt;:+word&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;parameter&lt;/span&gt;:offset:length&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;# substring expansion&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;some-one-liners-and-clever-ways-of-using-shell-script&quot;&gt;Some one-liners and clever ways of using shell script&lt;/h1&gt;
&lt;p&gt;Collected from internet over a period of time&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Remove strangely named files
    &lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;touch&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\-&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;test
rm&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-test&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# dangerous&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;rm&lt;/span&gt; ./-test &lt;span class=&quot;c&quot;&gt;# remove using ./&lt;/span&gt;
find &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-inum&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$inode&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-exec&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{}&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\;&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;# remmove by inode. Only way for file named &apos;01/01/2001&apos;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;As RPC
    &lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ssh user@remote &lt;span class=&quot;s2&quot;&gt;&quot;
     &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;declare&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; var1 var2 var3&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;
     &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;declare&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; func1 func2 remotemain&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;
     remotemain
   &quot;&lt;/span&gt;
ssh user@remote &lt;span class=&quot;s2&quot;&gt;&quot;dump_logs | gzip -c&quot;&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;gunzip&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt; | read_logs
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;find the longest string matching “*/” from first in $0
    &lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;##*/&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;find the longest string matching “b” from last in $string
    &lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%%b&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Find email addresses in a file
    &lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-E&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\.&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[A-Za-z]{2,6}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; file.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Print 5th to 10th line in file
    &lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;5,10p&apos;&lt;/span&gt; file                    &lt;span class=&quot;c&quot;&gt;# using sed&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;NR&amp;gt;=5{print} NR==10{exit}&apos;&lt;/span&gt; file   &lt;span class=&quot;c&quot;&gt;# using awk&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Extract lines between two patterns
    &lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;/pattern1/,/pattern2/p&apos;&lt;/span&gt; file
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Remove dups but preserve the order
    &lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;!visited[$0]++&apos;&lt;/span&gt; your_file &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; deduplicated_file
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Copy from bash to clipboard using OSC command
    &lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\0&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;33]52;c;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;base64&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;copy something here&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\a&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;Raise notification from terminal using OSC command
    &lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\0&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;33]9;This is a notification&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\a&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/dylanaraps/pure-bash-bible&quot;&gt;Pure Bash Bible&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://mywiki.wooledge.org/Bashism&quot;&gt;Bashism&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.davidpashley.com/articles/writing-robust-shell-scripts/&quot;&gt;Writing Robust Bash Shell Scripts&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.pixelbeat.org/programming/shell_script_mistakes.html&quot;&gt;Common shell script mistakes&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://mywiki.wooledge.org/BashPitfalls&quot;&gt;Bash Pitfalls&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://wiki.bash-hackers.org/&quot;&gt;The Bash Hackers Wiki&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 28 May 2020 05:14:37 +0000</pubDate>
        <link>https://vayudoot.org/shell/programming/2020/05/28/bash.html</link>
        <guid isPermaLink="true">https://vayudoot.org/shell/programming/2020/05/28/bash.html</guid>
        
        
        <category>shell</category>
        
        <category>programming</category>
        
      </item>
    
      <item>
        <title>Books read in 2019</title>
        <description>&lt;p&gt;All the books read in 2019.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;“Never split the difference” - Chris Voss, Tahl Raz&lt;/li&gt;
  &lt;li&gt;“The Cartoon Introduction to Economics: Volume One: Microeconomics” - Yoram Bauman, Grady Klein&lt;/li&gt;
  &lt;li&gt;“How to solve it” - G. Polya&lt;/li&gt;
  &lt;li&gt;“Seven Brief Lessons on Physics” - Carlo Rovelli&lt;/li&gt;
  &lt;li&gt;“On writing: A Memoir of the Craft” - Stephen King&lt;/li&gt;
  &lt;li&gt;“Immortal Talks- Book 1” - Shunya&lt;/li&gt;
  &lt;li&gt;“A mind for numbers: How to Excel at Math and Science (Even If You Flunked Algebra)” - Barbara Oakley&lt;/li&gt;
  &lt;li&gt;“Why I am an atheist” - Bhagat Singh&lt;/li&gt;
  &lt;li&gt;“Thinking in Systems: A primer” -  Donella H. Meadows&lt;/li&gt;
  &lt;li&gt;“The Supermen: The Story of Seymour Cray and the Technical Wizards Behind the Supercomputer” - Charles J. Murray&lt;/li&gt;
  &lt;li&gt;“Weird things customers say in bookshops” - Jen Campbell&lt;/li&gt;
  &lt;li&gt;“The Field Guide to Dumb Birds of North America” - Matt Kracht&lt;/li&gt;
  &lt;li&gt;“Scary stories to tell in the Dark” - Alvin Schwatz, Stephen Gammell&lt;/li&gt;
  &lt;li&gt;“More Scary stories to tell in the Dark” - Alvin Schwatz, Stephen Gammell&lt;/li&gt;
  &lt;li&gt;“Fearless Salary Negotiation” - Josh Doody&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 05 Jan 2020 05:28:07 +0000</pubDate>
        <link>https://vayudoot.org/books/2020/01/05/books-in-2019.html</link>
        <guid isPermaLink="true">https://vayudoot.org/books/2020/01/05/books-in-2019.html</guid>
        
        
        <category>books</category>
        
      </item>
    
      <item>
        <title>Memory aligned malloc</title>
        <description>&lt;p&gt;A very common interview question is to allocate memory aligned to given block size, such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memalign_malloc(size_t bytes, size_t align)&lt;/code&gt;. Despite being common, I have found that not many people really understand the implementation, including the interviewer. In practice, one would either totally avoid such aligned allocation (relying on machine natural alignment using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;malloc&lt;/code&gt;) or use native &lt;a href=&quot;https://www.gnu.org/software/libc/manual/html_node/Aligned-Memory-Blocks.html&quot;&gt;aligned_alloc(), or memalign(), or posix_memalign()&lt;/a&gt; family.&lt;/p&gt;

&lt;p&gt;When allocating memory through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;malloc&lt;/code&gt; (or its cousins), it returns a block of memory which is multiple of 8 or 16 for 32 or 64-bit system, resp. However, in some special cases such alignment might not be enough such as in an embedded system, while implementing your own memory manager (e.g. GC), for allocating specifically on page boundary, while interfacing with certaing I/O hardware, or for CPU cache alignment, and other such cases. Hence, there exists &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memalign&lt;/code&gt; and similar routines.&lt;/p&gt;

&lt;p&gt;To implement &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memalign_malloc&lt;/code&gt;, our first intution might be to allocate requested size block plus extra memory to adjust for misaligned address from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;malloc&lt;/code&gt;. However, if we return this new aligned address then while using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memalign_free&lt;/code&gt; we might leave a hole between &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;malloc&lt;/code&gt; returned address and aligned address, and possibly corrupt memory too. We need a place to save the original address as that is what should be used by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;free&lt;/code&gt; which would be eventually called by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memalign_free&lt;/code&gt;. Most memory allocators keep some metadata associated with each block of allocated memory which might contain block size, actual address, access/proection info, etc. For &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memalign_malloc&lt;/code&gt;, we would only store the original address as returned by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;malloc&lt;/code&gt; at some location. Our complementary &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memalign_free()&lt;/code&gt; would know where to pick this address from and eventually call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;free&lt;/code&gt; using this address.&lt;/p&gt;

&lt;p&gt;How much extra space should we allocate? It could be that the address returned by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;malloc&lt;/code&gt; needs adjustment by upto &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(align - 1)&lt;/code&gt;. So, we need to allocate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(align - 1)&lt;/code&gt; extra bytes just for this adjustment. Also, we need to save the original address as returned by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;malloc&lt;/code&gt;, which needs space equal to the size of a pointer for underlying machine. Total memory we allocate is -&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;extra&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;malloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;extra&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/static/img/memalign-a.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The trick for aligning an address is by masking the lower bits of address which correspond to alignment size such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;address &amp;amp; ~(align - 1)&lt;/code&gt;. So, if we were trying to align to 16 bytes, ~(16 - 1) or a mask of 0xF is required, since inverting only those bits and ‘and’ing would mean those many last bits would be 0 in address, i.e. new address will be multiple of 16. Note, that due to this calculation the alignment size can only be for power of 2. The new aligned address is going to be somewhere between &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mem&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mem + (align-1)&lt;/code&gt;. But we also need to save address &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mem&lt;/code&gt; and best location would be to store it right before new aligned address. So, best would be to find aligned address from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mem + sizeof(void *)&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mem + extra&lt;/code&gt;. Our new address will become &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(mem + extra) &amp;amp; ~(align-1)&lt;/code&gt;. But that’s not enough - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mem&lt;/code&gt; is pointer so we can’t do normal arithmatic with it. To circumvent that, we can typecast it to uintptr_t.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new_address&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uintptr_t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;extra&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;align&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/static/img/memalign-b.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now only remaining piece is how to save &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mem&lt;/code&gt;? We already know it must be saved right before new_address for easy acccess as well as to avoid being trampled by data. A neat trick is to treat this block of memory as an array to pointers, and then if arr[0] points to new_address, arr[-1] is where we can store &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mem&lt;/code&gt;. When treating block as an array, when we access previous or later element of array, stride will be exactly the size of element (in out case it would be void *), so now we dont need to typecast, add, subtract, etc. With that new address can also be seen as array of pointers.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ptr_array&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uintptr_t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;extra&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;align&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Notice use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(void **)&lt;/code&gt;. In C, array is nothing but contiguous block of memory. Its only when this block is accessed, one can access it as array (and move as much as size of element) or regular bytes. So array of interegers can be represented as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int arr[]&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int *arr&lt;/code&gt;. Hence, an array of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(void *)&lt;/code&gt; can be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;void *arr[]&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;void **arr&lt;/code&gt; and still one can use arr[0] format. That means in above code snippet, we can use ptr_array[-1] and it’ll be essentially &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(ptr_array - sizeof(void *))&lt;/code&gt;. That’s where we can save &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mem&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;ptr_array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/static/img/memalign-c.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;To free this memory block, all we need to do is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;free((void **)addr[-1])&lt;/code&gt;. With that our final code looks like following -&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;memalign_malloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;align&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;extra&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;malloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;extra&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ptr_array&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uintptr_t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;extra&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;align&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ptr_array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr_array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;memalign_free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Sat, 01 Jun 2019 16:22:07 +0000</pubDate>
        <link>https://vayudoot.org/cpp/programming/2019/06/01/memaligned-malloc.html</link>
        <guid isPermaLink="true">https://vayudoot.org/cpp/programming/2019/06/01/memaligned-malloc.html</guid>
        
        
        <category>cpp</category>
        
        <category>programming</category>
        
      </item>
    
      <item>
        <title>Life as summarized in Lisp</title>
        <description>&lt;p&gt;You have a right to perform your prescribed duty, but you are not entitled to the fruits of action. - &lt;em&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Bhagavad_Gita&quot;&gt;Bhagavad Gita&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;div class=&quot;language-common-lisp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;life&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;karma&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cond&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;null?&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;karma&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;&apos;moksha&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;life&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cdr&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;karma&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))))&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;karma&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ma&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;phaleshu&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;kadachana&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;life&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;karma&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Sat, 01 Jun 2019 07:15:49 +0000</pubDate>
        <link>https://vayudoot.org/others/2019/06/01/life-in-lisp.html</link>
        <guid isPermaLink="true">https://vayudoot.org/others/2019/06/01/life-in-lisp.html</guid>
        
        
        <category>others</category>
        
      </item>
    
      <item>
        <title>Welcome to digital enlightment</title>
        <description>&lt;p&gt;A new blog post using jekyll and github pages. The theme is taken from &lt;a href=&quot;https://agusmakmun.github.io/&quot;&gt;Agus Makmun&lt;/a&gt;’s layout and scantily modified.&lt;/p&gt;

&lt;p&gt;Another theme I liked was &lt;a href=&quot;https://apas.github.io/athena/&quot;&gt;Athena&lt;/a&gt; but could not make it work. Also tried using &lt;a href=&quot;http://octopress.org/&quot;&gt;Octopress&lt;/a&gt;, but will wait until version 3.0 is released.&lt;/p&gt;
</description>
        <pubDate>Sat, 01 Jun 2019 06:55:49 +0000</pubDate>
        <link>https://vayudoot.org/others/2019/06/01/welcome-to-digital-enlightment.html</link>
        <guid isPermaLink="true">https://vayudoot.org/others/2019/06/01/welcome-to-digital-enlightment.html</guid>
        
        
        <category>others</category>
        
      </item>
    
  </channel>
</rss>
